diff options
author | Mohit Mehta <mohit.mehta@vyatta.com> | 2009-01-20 15:39:12 -0800 |
---|---|---|
committer | Mohit Mehta <mohit.mehta@vyatta.com> | 2009-01-20 15:39:12 -0800 |
commit | e8767c28722861f8873353950a8d82c2be1636f2 (patch) | |
tree | 04da8e5bbaa5d189b72310306cc548067ad92f14 | |
parent | 84b93c4842d09f329607d2fdf94c6107823090ec (diff) | |
download | vyatta-nat-e8767c28722861f8873353950a8d82c2be1636f2.tar.gz vyatta-nat-e8767c28722861f8873353950a8d82c2be1636f2.zip |
Fix Bug 3287 Add the ability to configure the iptables "NETMAP" target via the CLI
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 |