summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohit Mehta <mohit.mehta@vyatta.com>2009-01-20 15:39:12 -0800
committerMohit Mehta <mohit.mehta@vyatta.com>2009-01-20 15:39:12 -0800
commite8767c28722861f8873353950a8d82c2be1636f2 (patch)
tree04da8e5bbaa5d189b72310306cc548067ad92f14
parent84b93c4842d09f329607d2fdf94c6107823090ec (diff)
downloadvyatta-nat-e8767c28722861f8873353950a8d82c2be1636f2.tar.gz
vyatta-nat-e8767c28722861f8873353950a8d82c2be1636f2.zip
Fix Bug 3287 Add the ability to configure the iptables "NETMAP" target via the CLI
-rw-r--r--lib/Vyatta/NatRule.pm61
-rw-r--r--templates-cfg/service/nat/rule/node.tag/inside-address/address/node.def1
-rw-r--r--templates-cfg/service/nat/rule/node.tag/outside-address/address/node.def1
3 files changed, 53 insertions, 10 deletions
diff --git a/lib/Vyatta/NatRule.pm b/lib/Vyatta/NatRule.pm
index 1603783..8a0670c 100644
--- a/lib/Vyatta/NatRule.pm
+++ b/lib/Vyatta/NatRule.pm
@@ -151,6 +151,8 @@ sub rule_str {
return (undef, 'cannot specify inbound interface with '
. '"masquerade" or "source" rules')
if (defined($self->{_inbound_if}));
+
+ my $use_netmap = 0;
if ($self->{_exclude}) {
$rule_str .= "-j RETURN";
@@ -177,9 +179,16 @@ sub rule_str {
my $to_src = '';
if (defined($self->{_outside_addr}->{_addr})) {
my $addr = $self->{_outside_addr}->{_addr};
- return (undef, "\"$addr\" is not a valid IP address")
- if (!Vyatta::TypeChecker::validateType('ipv4', $addr, 1));
- $to_src .= $addr;
+ if ($addr =~ m/\//) {
+ return (undef, "\"$addr\" is not a valid IPv4net address")
+ if (!Vyatta::TypeChecker::validateType('ipv4net', $addr, 1));
+ $to_src .= $addr;
+ $use_netmap = 1;
+ } else {
+ return (undef, "\"$addr\" is not a valid IP address")
+ if (!Vyatta::TypeChecker::validateType('ipv4', $addr, 1));
+ $to_src .= $addr;
+ }
} elsif (defined($self->{_outside_addr}->{_range}->{_start})
&& defined($self->{_outside_addr}->{_range}->{_stop})) {
my $start = $self->{_outside_addr}->{_range}->{_start};
@@ -199,6 +208,10 @@ sub rule_str {
return (undef, "ports can only be specified when protocol is \"tcp\" "
. "or \"udp\" (currently \"$self->{_proto}\")");
}
+ if ($use_netmap) {
+ return (undef, "Cannot use ports with an IPv4net type outside-address as it
+statically maps a whole network of addresses onto another network of addresses");
+ }
if ($self->{_type} ne "masquerade") {
$to_src .= ":";
}
@@ -221,7 +234,13 @@ sub rule_str {
if ($self->{_type} eq "masquerade") {
$rule_str .= " --to-ports $to_src";
} else {
- $rule_str .= " --to-source $to_src";
+ if ($use_netmap) {
+ # replace "SNAT" with "NETMAP"
+ $rule_str =~ s/SNAT/NETMAP/;
+ $rule_str .= " --to $to_src";
+ } else {
+ $rule_str .= " --to-source $to_src";
+ }
}
} elsif ($self->{_type} ne "masquerade") {
return (undef, "outside-address not specified");
@@ -232,6 +251,8 @@ sub rule_str {
'cannot specify outbound interface with "destination" rules')
if (defined($self->{_outbound_if}));
+ my $use_netmap = 0;
+
if ($self->{_exclude}) {
$rule_str .= "-j RETURN";
} else {
@@ -250,12 +271,21 @@ sub rule_str {
$rule_str .= " -p $self->{_proto}";
}
- my $to_dst = " --to-destination ";
+ my $to_dst = "";
if (defined($self->{_inside_addr}->{_addr})) {
my $addr = $self->{_inside_addr}->{_addr};
- return (undef, "\"$addr\" is not a valid IP address")
- if (!Vyatta::TypeChecker::validateType('ipv4', $addr, 1));
- $to_dst .= $addr;
+ if ($addr =~ m/\//) {
+ return (undef, "\"$addr\" is not a valid IPv4net address")
+ if (!Vyatta::TypeChecker::validateType('ipv4net', $addr, 1));
+ $to_dst = " --to ";
+ $to_dst .= $addr;
+ $use_netmap = 1;
+ } else {
+ return (undef, "\"$addr\" is not a valid IP address")
+ if (!Vyatta::TypeChecker::validateType('ipv4', $addr, 1));
+ $to_dst = " --to-destination ";
+ $to_dst .= $addr;
+ }
} elsif (defined($self->{_inside_addr}->{_range}->{_start})
&& defined($self->{_inside_addr}->{_range}->{_stop})) {
my $start = $self->{_inside_addr}->{_range}->{_start};
@@ -263,6 +293,7 @@ sub rule_str {
return (undef, "\"$start-$stop\" is not a valid IP range")
if (!Vyatta::TypeChecker::validateType('ipv4', $start, 1)
|| !Vyatta::TypeChecker::validateType('ipv4', $stop, 1));
+ $to_dst = " --to-destination ";
$to_dst .= "$start-$stop";
}
@@ -271,6 +302,10 @@ sub rule_str {
return (undef, "ports can only be specified when protocol is \"tcp\" "
. "or \"udp\" (currently \"$self->{_proto}\")");
}
+ if ($use_netmap) {
+ return (undef, "Cannot use ports with an IPv4net type outside-address as it
+statically maps a whole network of addresses onto another network of addresses");
+ }
my ($success, $err) = (undef, undef);
if ($self->{_inside_addr}->{_port} =~ /-/) {
($success, $err)
@@ -286,8 +321,14 @@ sub rule_str {
if ($self->{_exclude}) {
# inside-address has no effect for "exclude" rules
- } elsif ($to_dst ne ' --to-destination ') {
- $rule_str .= $to_dst;
+ } elsif ($to_dst ne "") {
+ if ($use_netmap) {
+ # replace "DNAT" with "NETMAP"
+ $rule_str =~ s/DNAT/NETMAP/;
+ $rule_str .= " $to_dst";
+ } else {
+ $rule_str .= " $to_dst";
+ }
} else {
return (undef, "inside-address not specified");
}
diff --git a/templates-cfg/service/nat/rule/node.tag/inside-address/address/node.def b/templates-cfg/service/nat/rule/node.tag/inside-address/address/node.def
index 910ae61..5786af9 100644
--- a/templates-cfg/service/nat/rule/node.tag/inside-address/address/node.def
+++ b/templates-cfg/service/nat/rule/node.tag/inside-address/address/node.def
@@ -3,3 +3,4 @@ help: Set inside IP address or range for NAT
comp_help: Possible completions:
<x.x.x.x> NAT to the specified IP address
<x.x.x.x>-<x.x.x.x> NAT to the specified IP range
+ <x.x.x.x/x> NAT to the specified network address. Host part of the address will remain unchanged
diff --git a/templates-cfg/service/nat/rule/node.tag/outside-address/address/node.def b/templates-cfg/service/nat/rule/node.tag/outside-address/address/node.def
index 0bfb506..67add07 100644
--- a/templates-cfg/service/nat/rule/node.tag/outside-address/address/node.def
+++ b/templates-cfg/service/nat/rule/node.tag/outside-address/address/node.def
@@ -3,3 +3,4 @@ help: Set outside IP address or range for NAT
comp_help: Possible completions:
<x.x.x.x> NAT to the specified IP address
<x.x.x.x>-<x.x.x.x> NAT to the specified IP range
+ <x.x.x.x/x> NAT to the specified network address. Host part of the address will remain unchanged