11 Commits
v1.2 ... v1.4

Author SHA1 Message Date
Tore Anderson
aa92cb0287 Bump version to v1.4 2015-10-23 13:43:34 +02:00
Tore Anderson
5e2297903a Improve handing of single-scalar calls to cmd()
Just pass the entire supplied command line, be it a single scalar or an array,
to system(). It'll do the right thing with it. This gets rid of a spurious
trailing space in debugging output when cmd() was called with a single scalar
as the command argument (leaving @cmdline undefined).
2015-10-23 11:49:51 +02:00
Tore Anderson
f976f46b57 Correct debug output for cfg() and cfgint() 2015-10-23 11:35:03 +02:00
Tore Anderson
e8cb719f10 Insert the effective default advmss into %CFG
This ensures that the effective value (rather than the configured value or lack
thereof) is available in the environment of script-up/down.
2015-10-23 11:33:35 +02:00
Tore Anderson
0bc3bbd797 New feature: script-up/down
Adds the possibility of making clatd run a custom script while starting up or
shutting down.
2015-10-23 11:22:00 +02:00
Tore Anderson
a80e2f30ab New feature: Set advmss on IPv4 default route
This ensures that TCP connections terminated through the CLAT gets a sensible
TCP MSS value negotiated. By default, the value is set to the MTU of the
defaultroute minus 40. There should be no reason to change this in the vast
majority of cases, but it can be overridden with the "v4-defaultroute-advmss"
setting.
2015-10-22 11:58:19 +02:00
Tore Anderson
9f1789f34d New feature: Replace original IPv4 default route
Adds "v4-defaultroute-replace" config/command-line setting (default disabled).
When enabled, it will unconditionally disable the pre-flight IPv4 connectivity
check, and ensure that any pre-existing IPv4 default routes are removed during
startup (and presumably replaced with the one pointing to the CLAT, unless
"v4-defaultroute-enable" has been disabled). Any IPv4 default routes that were
removed in this manner are restored when clatd is shutting down.
2015-10-22 11:12:34 +02:00
Tore Anderson
2f2a59ddf3 v1.3: new licence => new release 2015-07-23 13:40:17 +02:00
Tore Anderson
b5725c093c relicence to MIT to make lrintel happy 2015-07-23 13:38:30 +02:00
Tore Anderson
ad114b18cf Update for siit-dc ietf changes
- the siit-dc drafts have been adopted by the v6ops wg
- host agent renamed to edge relay
2015-07-23 13:29:28 +02:00
Tore Anderson
c48ad644c0 Avoid a restart loop with NM dispatcher scripts
Newer NetworkManager versions will run the dispatcher scripts when new
unknown interfaces show up, including 'clat'. That will cause a clatd
restart right after startup, and we'll never get to fully initialise. So
ensure the dispatcher script does nothing if the device in question is
our own 'clat' to prevent this.
2014-10-05 20:27:07 +02:00
4 changed files with 196 additions and 38 deletions

22
LICENCE
View File

@@ -1,5 +1,19 @@
Copyright (c) 2014 Tore Anderson <tore@fud.no>
Copyright (c) 2014-2015 Tore Anderson <tore@fud.no>
As long as you retain this notice, you may use this piece of software as
you wish. If you like it, and we happen to meet one day, you can buy me
a beer in return. If you really like it, make it an IPA.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,6 +1,6 @@
=head1 NAME
B<clatd> - a CLAT / SIIT-DC Host Agent implementation for Linux
B<clatd> - a CLAT / SIIT-DC Edge Relay implementation for Linux
=head1 DESCRIPTION
@@ -13,12 +13,12 @@ local applications on the host requires actual IPv4 connectivity or cannot
make use of DNS64 (for example because they use legacy AF_INET socket calls,
or if they are simply not using DNS64).
It may also be used to implement an SIIT-DC Host Agent as defined by
I<I-D.anderson-v6ops-siit-dc-2xlat>. In this scenario, the PLAT is a SIIT-DC
Gateway (see I<I-D.anderson-v6ops-siit-dc>) instead of a Stateful NAT64 (see
I<RFC6146>). When used as a SIIT-DC Host Agent, you will probably want to
manually configure the settings I<clat-v4-addr>, I<clat-v6-addr>, and
I<plat-prefix> to mirror the SIIT-DC Gateway's configuration.
B<clatd> may also be used to implement an SIIT-DC Edge Relay as described in
I<I-D.ietf-v6ops-siit-dc-2xlat>. In this scenario, the PLAT is in reality a
SIIT-DC Border Relay (see I<I-D.ietf-v6ops-siit-dc>) instead of a Stateful
NAT64 (see I<RFC6146>). When used as a SIIT-DC Edge Relay, you will probably
want to manually configure the settings I<clat-v4-addr>, I<clat-v6-addr>, and
I<plat-prefix> to mirror the SIIT-DC Border Relay's configuration.
It relies on the software package TAYGA by Nathan Lutchansky for the actual
translation of packets between IPv4 and IPv6 (I<RFC 6145>) TAYGA may be
@@ -119,6 +119,57 @@ Set this to 1 to get debugging output from B<clatd>, or 2 to get even more of
the stuff. These are the equivalent of providing the command line option I<-d>
the specified number of times.
=item B<script-up=string> (no default)
Specify a custom script to be run when B<clatd> is starting up. The invocation
of this script is the last thing that happens before TAYGA starts up, so all
the preparations have been completed at that point (i.e., the B<clat-dev>
exists and has routing/addressing configured, forwarding has been enabled, and
so on).
The script is run by the system shell, so you can do everything you could in an
interactive shell: run multiple commands by separating them by semi-colon or
double ampersands, use standard if/else statements, use variable substitutions,
redirect output to files, set up command pipelines, and so on. However it must
all be on one line, so if you want to do complex things or use some other
programming language it's probably better to put the script itself in a
separate executable file and just make B<script-up> invoke that file instead.
If the script returns a nonzero exit status, this is considered a fatal error,
and B<clatd> will abort. This can be prevented by appending I<|| true> at the
end of the script.
All of B<clatd>'s configuration settings are available as standard variables in
the script's environment (hyphens are replaced with underscores).
Logging or debug messages from the script may simply be sent to stdout, where
it will be picked up by the init system along with B<clatd>'s own output. The
script may of course consult the I<$quiet> and I<$debug> environment variables
in order to determine how much output is appropriate.
The script should not be enclosed in quotes in the configuration file (even
though it contains whitespace). For example:
B<script-up=echo `date -Ins`: clatd started on $clat_dev | tee -a ~/clatd.log>
If on the other hand you want to supply a B<script-up> containing whitespace
directly B<clatd>'s command line, quoting is required in order to prevent the
shell from splitting it up and into multiple command line arguments. For
example:
B<clatd 'script-up=ip route add 192.0.2.0/24 dev $clat_dev || true'>
=item B<script-up=string> (no default)
This works exactly the same as B<script-up>, only that this script is run right
after TAYGA has exited, before the clean-up process of restoring any settings
that were changed.
An unsuccessful exit code from B<script-down> will cause B<clatd> to exit
unsuccessfully too. Beyond that an unsuccessful exit won't change anything,
because B<script-down> is invoked at a point in time where the only thing left
for B<clatd> to do is to clean up after itself and exit anyway.
=item B<clat-dev=string> (default: I<clat>)
The name of the network device used by the CLAT. There should be no reason to
@@ -132,21 +183,20 @@ will bind to this address when communicating with external IPv4 destinations.
In a standard 464XLAT environment with a stateful NAT64 serving as the PLAT,
there should be no need to change the default.
When using B<clatd> as an SIIT-DC Host Agent (cf.
I-D.draft-anderson-v6ops-siit-dc-2xlat), you will want to set this to the
IPv4 Service Address configured in the SIIT-DC Gateway. This way, local
applications can correctly identify which public address they'll be using on
the IPv4 internet, and will be able to provide fully functional references to
it in application-level payload, and so on.
When using B<clatd> as an SIIT-DC Edge Relay (I<I-D.ietf-v6ops-siit-dc-2xlat>),
you will want to set this to the IPv4 Service Address configured in the SIIT-DC
Border Relay. This way, local applications can correctly identify which public
address they'll be using on the IPv4 internet, and will be able to provide
fully functional references to it in application-level payload, and so on.
The default address is one from I<RFC 7335>.
=item B<clat-v6-addr=ipv6-address> (default: auto-generated)
The IPv6 address of the CLAT. Traffic to/from the B<clat-v4-addr> will be
translated into this address. When using B<clatd> as an SIIT-DC Host Agent,
you will want to set this to the IPv6 address in the Static Address Mapping
configured in the SIIT-DC Gateway.
translated into this address. When using B<clatd> as an SIIT-DC Edge Relay, you
will want to set this to the same IPv6 address in the Explicit Address Mapping
configured in the SIIT-DC Border Relay.
By default, B<clatd> will attempt to figure out which network device will be
used for traffic towards the PLAT, see if there is any SLAAC-based globally
@@ -267,6 +317,9 @@ system has IPv4 connectivity, disable this setting. You may instead use the
B<v4-defaultroute-enable> and B<v4-defaultroute-metric> settings to prevent
B<clatd> from interfering with native IPv4 connectivity.
Note that enabling B<v4-defaultroute-replace> will override
B<v4-conncheck-enable> and unconditionally disable IPv4 connectivity checking.
=item B<v4-conncheck-delay=seconds> (default: I<10>)
When performing an IPv4 connectivity check, wait this number of seconds
@@ -287,6 +340,23 @@ an environment where native IPv4 connectivity is also present, you might want
to disable this and instead control manually which IPv4 destinations is
reached through the CLAT and which are not.
=item B<v4-defaultroute-replace=bool> (default: I<no>)
Instructs B<clatd> to remove any pre-existing IPv4 default routes, replacing it
with one pointing to the CLAT (assuming B<v4-defaultroute-enable> is I<yes>).
The replacement is temporary, any pre-existing routes that were removed will be
restored when B<clatd> is shutting down.
Note that nothing prevents software like a connection manager or a DHCPv4
client daemon from re-adding any replaced routes while B<clatd> is running.
If you enable B<v4-defaultroute-replace> while at the same time disabling
B<v4-defaultroute-enable>, B<clatd> will remove any pre-existing IPv4 default
routes but not add any of its own.
Setting B<v4-defaultroute-replace> to I<yes>will disable the IPv4 connectivity
check.
=item B<v4-defaultroute-metric=integer> (default: I<2048>)
The metric of the IPv4 default route pointing to the CLAT. The default is
@@ -307,6 +377,17 @@ If you know that the IPv6 Path MTU between the host and the PLAT is larger
than 1280, you may increase this, but then you should also recompile TAYGA
with a larger B<ipv6_offlink_mtu> setting in I<conffile.c>.
=item B<v4-defaultroute-advmss=integer> (default: B<v4-defaultroute-mtu> - 40)
The "advmss" value assigned to the the default route potining to the CLAT. This
controls the advertised TCP MSS value for TCP connections made through the
CLAT.
You should normally not need to set this. By default the value is calculated by
taking the value of B<v4-defaultroute-mtu> and substracting 40 (20 bytes for
the IPv4 header + 20 bytes for the TCP header). If B<v4-defaultroute-mtu> is
unset or 0, there is no default.
=back
=head1 LIMITATIONS
@@ -331,11 +412,25 @@ configuration file) when reporting a bug.
=head1 LICENCE
Copyright (c) 2014 Tore Anderson <tore@fud.no>
Copyright (c) 2014-2015 Tore Anderson <tore@fud.no>
As long as you retain this notice, you may use this piece of software as
you wish. If you like it, and we happen to meet one day, you can buy me
a beer in return. If you really like it, make it an IPA.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
=head1 SEE ALSO
@@ -343,6 +438,6 @@ ip(8), ip6tables(8), tayga(8), tayga.conf(5)
RFC 6052, RFC 6145, RFC 6146, RFC 6877, RFC 7050, RFC 7335
I-D.anderson-v6ops-siit-dc, I-D.anderson-v6ops-siit-dc-2xlat
I-D.ietf-v6ops-siit-dc, I-D.ietf-v6ops-siit-dc-2xlat, I-D.ietf-v6ops-siit-eam
=cut

68
clatd
View File

@@ -12,7 +12,7 @@
use strict;
use Net::IP;
my $VERSION = "1.2";
my $VERSION = "1.4";
#
# Populate the global config hash with the default values
@@ -20,6 +20,8 @@ my $VERSION = "1.2";
my %CFG;
$CFG{"quiet"} = 0; # suppress normal output
$CFG{"debug"} = 0; # debugging output level
$CFG{"script-up"} = undef; # sh script to run when starting up
$CFG{"script-down"} = undef; # sh script to run when shutting down
$CFG{"clat-dev"} = "clat"; # TUN interface name to use
$CFG{"clat-v4-addr"} = "192.0.0.1"; # from RFC 7335
$CFG{"clat-v6-addr"} = undef; # derive from existing SLAAC addr
@@ -37,8 +39,10 @@ $CFG{"tayga-v4-addr"} = "192.0.0.2"; # from RFC 7335
$CFG{"v4-conncheck-enable"} = 1; # exit if there's already a defroute
$CFG{"v4-conncheck-delay"} = 10; # seconds before checking for v4 conn.
$CFG{"v4-defaultroute-enable"} = 1; # add a v4 defaultroute via the CLAT?
$CFG{"v4-defaultroute-replace"} = 0; # replace existing v4 defaultroute?
$CFG{"v4-defaultroute-metric"} = 2048; # metric for the IPv4 defaultroute
$CFG{"v4-defaultroute-mtu"} = 1260; # MTU for the IPv4 defaultroute
$CFG{"v4-defaultroute-advmss"} = 0; # TCP MSS for the IPv4 defaultroute
#
@@ -69,18 +73,17 @@ sub err {
#
sub cmd {
my $msgsub = shift;
my $command = shift;
my @cmdline = @_;
my @cmd = @_;
d("cmd($command @cmdline)");
d("cmd(@cmd)");
if(system($command, @cmdline)) {
if(system(@cmd)) {
if($? == -1) {
&{$msgsub}("cmd($command @cmdline) failed to execute");
&{$msgsub}("cmd(@cmd) failed to execute");
} elsif($? & 127) {
&{$msgsub}("cmd($command @cmdline) died with signal ", ($? & 127));
&{$msgsub}("cmd(@cmd) died with signal ", ($? & 127));
} else {
&{$msgsub}("cmd($command @cmdline) returned ", ($? >> 127));
&{$msgsub}("cmd(@cmd) returned ", ($? >> 127));
}
}
return $?;
@@ -135,7 +138,7 @@ sub cfgbool {
#
sub cfgint {
my ($key) = @_;
d2("cfgstr($key)");
d2("cfgint($key)");
if(!exists($CFG{$key})) {
err("key '$key' doesn't exist in config hash");
}
@@ -150,7 +153,7 @@ sub cfgint {
#
sub cfg {
my ($key) = @_;
d2("cfgstr($key)");
d2("cfg($key)");
if(!exists($CFG{$key})) {
err("key '$key' doesn't exist in config hash");
}
@@ -569,6 +572,7 @@ my @cleanup_accept_ra_sysctls; # accept_ra sysctls to be reset to '1'
my $cleanup_zero_proxynd_sysctl; # zero proxy_ndp sysctl if set
my $cleanup_remove_proxynd_entry, # true if having added proxynd entry
my $cleanup_remove_ip6tables_rules; # true if having added ip6tables rules
my @cleanup_restore_v4_defaultroutes; # temporarily replaced defaultroutes
sub cleanup_and_exit {
my $exitcode = shift;
@@ -608,6 +612,10 @@ sub cleanup_and_exit {
cmd(\&w, cfg("cmd-ip6tables"), qw(-D FORWARD -i), cfg("plat-dev"),
"-o", cfg("clat-dev"), qw(-j ACCEPT));
}
for my $rt (@cleanup_restore_v4_defaultroutes) {
d("Cleanup: Restoring temporarily replaced IPv4 default route");
cmd(\&w, cfg("cmd-ip"), qw(-4 route add), @{$rt});
}
exit($exitcode);
}
@@ -725,12 +733,15 @@ p("Using CLAT IPv6 address: ", $CFG{"clat-v6-addr"});
if(!defined($CFG{"ip6tables-enable"})) {
$CFG{"ip6tables-enable"} = -e "/sys/module/ip6table_filter" ? 1 : 0;
}
if(!$CFG{"v4-defaultroute-advmss"} and cfgint("v4-defaultroute-mtu")) {
$CFG{"v4-defaultroute-advmss"} = $CFG{"v4-defaultroute-mtu"} - 40;
}
#
# Step 1: Detect if there is an IPv4 default route on the system from before.
# If so we have no need for 464XLAT, and we can just exit straight away
#
if(cfgbool("v4-conncheck-enable")) {
if(cfgbool("v4-conncheck-enable") and !cfgbool("v4-defaultroute-replace")) {
my $delay = cfgint("v4-conncheck-delay");
p("Checking if this system already has IPv4 connectivity ",
$delay ? "in $delay sec(s)" : "now");
@@ -845,18 +856,44 @@ cmd(\&err, cfg("cmd-ip"), qw(-4 address add), cfg("clat-v4-addr"),
"dev", cfg("clat-dev"));
cmd(\&err, cfg("cmd-ip"), qw(-6 route add), cfg("clat-v6-addr"),
"dev", cfg("clat-dev"));
if(cfgbool("v4-defaultroute-replace")) {
open(my $fd, '-|', cfg("cmd-ip"), qw(-4 route show default))
or err("'ip -4 route show default' failed to execute");
while(<$fd>) {
my @rt = split(/\s+/, $_);
d("Replacing pre-existing IPv4 default route: @rt");
cmd(\&err, cfg("cmd-ip"), qw(-4 route del), @rt);
push(@cleanup_restore_v4_defaultroutes, \@rt);
}
close($fd) or err("'ip -4 route show default' failed");
}
if(cfgbool("v4-defaultroute-enable")) {
my @cmdline = (qw(-4 route add default dev), cfg("clat-dev"));
if(cfgint("v4-defaultroute-metric")) {
push(@cmdline, ("metric", cfgint("v4-defaultroute-metric")))
}
if(cfgint("v4-defaultroute-mtu")) {
push(@cmdline, ("mtu", cfgint("v4-defaultroute-mtu")))
push(@cmdline, ("mtu", cfgint("v4-defaultroute-mtu")));
}
if(cfgint("v4-defaultroute-advmss")) {
push(@cmdline, ("advmss", cfgint("v4-defaultroute-advmss")));
}
p("Adding IPv4 default route via the CLAT");
cmd(\&err, cfg("cmd-ip"), @cmdline);
}
# Inject %CFG into %ENV and then run the up script
for my $key (sort keys(%CFG)) {
my $var = $key;
$var =~ y/-/_/;
d2(sprintf("Script env: %s=%s", $key, $CFG{$key} || ''));
$ENV{$var} = $CFG{$key};
}
if(cfg("script-up")) {
d("Running custom startup script: ", cfg("script-up"));
cmd(\&err, cfg("script-up"));
}
#
# All preparation done! We can now start TAYGA, which will handle the actual
# translation of IP packets.
@@ -877,6 +914,11 @@ $SIG{'INT'} = 'DEFAULT';
$SIG{'TERM'} = 'DEFAULT';
#
# TAYGA exited, probably because we're shutting down. Cleanup and exit.
# TAYGA exited, probably because we're shutting down. Run the down script, then
# cleanup and exit.
#
if(cfg("script-down")) {
d("Running custom shutdown script: ", cfg("script-down"));
cmd(\&err, cfg("script-down"));
}
cleanup_and_exit(0);

View File

@@ -7,6 +7,13 @@
# Written by Tore Anderson <tore@fud.no>
#
# Newer NetworkManager versions will run the dispatcher scripts once
# a new unmanaged interface shows up, including the 'clat' interface
# created by clatd/TAYGA. So if we're being called due to our own
# interface showing up, do nothing, otherwise we will end up
# committing suicide from the restarts below
[ "$DEVICE_IFACE" = "clat" ] && exit 0
# We simply restart clatd in all situations, as no matter if an interface
# goes up or down, it may mean that the PLAT device changes, it may mean
# native IPv4 appearing or disappearing, or it may mean that DNS64 became