Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa92cb0287 | ||
|
|
5e2297903a | ||
|
|
f976f46b57 | ||
|
|
e8cb719f10 | ||
|
|
0bc3bbd797 | ||
|
|
a80e2f30ab | ||
|
|
9f1789f34d |
82
README.pod
82
README.pod
@@ -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 stuff. These are the equivalent of providing the command line option I<-d>
|
||||||
the specified number of times.
|
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>)
|
=item B<clat-dev=string> (default: I<clat>)
|
||||||
|
|
||||||
The name of the network device used by the CLAT. There should be no reason to
|
The name of the network device used by the CLAT. There should be no reason to
|
||||||
@@ -266,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<v4-defaultroute-enable> and B<v4-defaultroute-metric> settings to prevent
|
||||||
B<clatd> from interfering with native IPv4 connectivity.
|
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>)
|
=item B<v4-conncheck-delay=seconds> (default: I<10>)
|
||||||
|
|
||||||
When performing an IPv4 connectivity check, wait this number of seconds
|
When performing an IPv4 connectivity check, wait this number of seconds
|
||||||
@@ -286,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
|
to disable this and instead control manually which IPv4 destinations is
|
||||||
reached through the CLAT and which are not.
|
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>)
|
=item B<v4-defaultroute-metric=integer> (default: I<2048>)
|
||||||
|
|
||||||
The metric of the IPv4 default route pointing to the CLAT. The default is
|
The metric of the IPv4 default route pointing to the CLAT. The default is
|
||||||
@@ -306,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
|
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>.
|
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
|
=back
|
||||||
|
|
||||||
=head1 LIMITATIONS
|
=head1 LIMITATIONS
|
||||||
|
|||||||
68
clatd
68
clatd
@@ -12,7 +12,7 @@
|
|||||||
use strict;
|
use strict;
|
||||||
use Net::IP;
|
use Net::IP;
|
||||||
|
|
||||||
my $VERSION = "1.3";
|
my $VERSION = "1.4";
|
||||||
|
|
||||||
#
|
#
|
||||||
# Populate the global config hash with the default values
|
# Populate the global config hash with the default values
|
||||||
@@ -20,6 +20,8 @@ my $VERSION = "1.3";
|
|||||||
my %CFG;
|
my %CFG;
|
||||||
$CFG{"quiet"} = 0; # suppress normal output
|
$CFG{"quiet"} = 0; # suppress normal output
|
||||||
$CFG{"debug"} = 0; # debugging output level
|
$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-dev"} = "clat"; # TUN interface name to use
|
||||||
$CFG{"clat-v4-addr"} = "192.0.0.1"; # from RFC 7335
|
$CFG{"clat-v4-addr"} = "192.0.0.1"; # from RFC 7335
|
||||||
$CFG{"clat-v6-addr"} = undef; # derive from existing SLAAC addr
|
$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-enable"} = 1; # exit if there's already a defroute
|
||||||
$CFG{"v4-conncheck-delay"} = 10; # seconds before checking for v4 conn.
|
$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-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-metric"} = 2048; # metric for the IPv4 defaultroute
|
||||||
$CFG{"v4-defaultroute-mtu"} = 1260; # MTU 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 {
|
sub cmd {
|
||||||
my $msgsub = shift;
|
my $msgsub = shift;
|
||||||
my $command = shift;
|
my @cmd = @_;
|
||||||
my @cmdline = @_;
|
|
||||||
|
|
||||||
d("cmd($command @cmdline)");
|
d("cmd(@cmd)");
|
||||||
|
|
||||||
if(system($command, @cmdline)) {
|
if(system(@cmd)) {
|
||||||
if($? == -1) {
|
if($? == -1) {
|
||||||
&{$msgsub}("cmd($command @cmdline) failed to execute");
|
&{$msgsub}("cmd(@cmd) failed to execute");
|
||||||
} elsif($? & 127) {
|
} elsif($? & 127) {
|
||||||
&{$msgsub}("cmd($command @cmdline) died with signal ", ($? & 127));
|
&{$msgsub}("cmd(@cmd) died with signal ", ($? & 127));
|
||||||
} else {
|
} else {
|
||||||
&{$msgsub}("cmd($command @cmdline) returned ", ($? >> 127));
|
&{$msgsub}("cmd(@cmd) returned ", ($? >> 127));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $?;
|
return $?;
|
||||||
@@ -135,7 +138,7 @@ sub cfgbool {
|
|||||||
#
|
#
|
||||||
sub cfgint {
|
sub cfgint {
|
||||||
my ($key) = @_;
|
my ($key) = @_;
|
||||||
d2("cfgstr($key)");
|
d2("cfgint($key)");
|
||||||
if(!exists($CFG{$key})) {
|
if(!exists($CFG{$key})) {
|
||||||
err("key '$key' doesn't exist in config hash");
|
err("key '$key' doesn't exist in config hash");
|
||||||
}
|
}
|
||||||
@@ -150,7 +153,7 @@ sub cfgint {
|
|||||||
#
|
#
|
||||||
sub cfg {
|
sub cfg {
|
||||||
my ($key) = @_;
|
my ($key) = @_;
|
||||||
d2("cfgstr($key)");
|
d2("cfg($key)");
|
||||||
if(!exists($CFG{$key})) {
|
if(!exists($CFG{$key})) {
|
||||||
err("key '$key' doesn't exist in config hash");
|
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_zero_proxynd_sysctl; # zero proxy_ndp sysctl if set
|
||||||
my $cleanup_remove_proxynd_entry, # true if having added proxynd entry
|
my $cleanup_remove_proxynd_entry, # true if having added proxynd entry
|
||||||
my $cleanup_remove_ip6tables_rules; # true if having added ip6tables rules
|
my $cleanup_remove_ip6tables_rules; # true if having added ip6tables rules
|
||||||
|
my @cleanup_restore_v4_defaultroutes; # temporarily replaced defaultroutes
|
||||||
|
|
||||||
sub cleanup_and_exit {
|
sub cleanup_and_exit {
|
||||||
my $exitcode = shift;
|
my $exitcode = shift;
|
||||||
@@ -608,6 +612,10 @@ sub cleanup_and_exit {
|
|||||||
cmd(\&w, cfg("cmd-ip6tables"), qw(-D FORWARD -i), cfg("plat-dev"),
|
cmd(\&w, cfg("cmd-ip6tables"), qw(-D FORWARD -i), cfg("plat-dev"),
|
||||||
"-o", cfg("clat-dev"), qw(-j ACCEPT));
|
"-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);
|
exit($exitcode);
|
||||||
}
|
}
|
||||||
@@ -725,12 +733,15 @@ p("Using CLAT IPv6 address: ", $CFG{"clat-v6-addr"});
|
|||||||
if(!defined($CFG{"ip6tables-enable"})) {
|
if(!defined($CFG{"ip6tables-enable"})) {
|
||||||
$CFG{"ip6tables-enable"} = -e "/sys/module/ip6table_filter" ? 1 : 0;
|
$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.
|
# 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 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");
|
my $delay = cfgint("v4-conncheck-delay");
|
||||||
p("Checking if this system already has IPv4 connectivity ",
|
p("Checking if this system already has IPv4 connectivity ",
|
||||||
$delay ? "in $delay sec(s)" : "now");
|
$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"));
|
"dev", cfg("clat-dev"));
|
||||||
cmd(\&err, cfg("cmd-ip"), qw(-6 route add), cfg("clat-v6-addr"),
|
cmd(\&err, cfg("cmd-ip"), qw(-6 route add), cfg("clat-v6-addr"),
|
||||||
"dev", cfg("clat-dev"));
|
"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")) {
|
if(cfgbool("v4-defaultroute-enable")) {
|
||||||
my @cmdline = (qw(-4 route add default dev), cfg("clat-dev"));
|
my @cmdline = (qw(-4 route add default dev), cfg("clat-dev"));
|
||||||
if(cfgint("v4-defaultroute-metric")) {
|
if(cfgint("v4-defaultroute-metric")) {
|
||||||
push(@cmdline, ("metric", cfgint("v4-defaultroute-metric")))
|
push(@cmdline, ("metric", cfgint("v4-defaultroute-metric")))
|
||||||
}
|
}
|
||||||
if(cfgint("v4-defaultroute-mtu")) {
|
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");
|
p("Adding IPv4 default route via the CLAT");
|
||||||
cmd(\&err, cfg("cmd-ip"), @cmdline);
|
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
|
# All preparation done! We can now start TAYGA, which will handle the actual
|
||||||
# translation of IP packets.
|
# translation of IP packets.
|
||||||
@@ -877,6 +914,11 @@ $SIG{'INT'} = 'DEFAULT';
|
|||||||
$SIG{'TERM'} = '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);
|
cleanup_and_exit(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user