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.
This commit is contained in:
Tore Anderson
2015-10-22 11:12:34 +02:00
parent 2f2a59ddf3
commit 9f1789f34d
2 changed files with 38 additions and 1 deletions

View File

@@ -266,6 +266,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
@@ -286,6 +289,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

19
clatd
View File

@@ -37,6 +37,7 @@ $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
@@ -569,6 +570,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 +610,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);
}
@@ -730,7 +736,7 @@ if(!defined($CFG{"ip6tables-enable"})) {
# 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,6 +851,17 @@ 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")) {