From a2e3e0b79622c1f30665c83a26351a1715a130ab Mon Sep 17 00:00:00 2001 From: William Brown Date: Wed, 15 Apr 2020 10:45:50 +1000 Subject: [PATCH] clatd support for networkmanager environments Systems that use network manager (typically clients, which is where clatd will be deployed) have some unique issues with clatd, because nm controls the whole stack in ways that break clatd. Generally this means that nm disables the forwarding flags on the interfaces, which causes traffic to not operate as expected. This adds support to manually reset the plat dev forwarding flag in the situation that nm or other tools have disabled it. --- clatd | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/clatd b/clatd index 1003d00..e4c3268 100755 --- a/clatd +++ b/clatd @@ -579,6 +579,7 @@ sub get_clat_v6_addr { my $cleanup_remove_clat_dev; # true if having created it my $cleanup_delete_taygaconf; # true if having made a temp confile my $cleanup_zero_forwarding_sysctl; # zero forwarding sysctl if set +my $cleanup_zero_forwarding_platdev_sysctl; # zero forwarding sysctl if set on platdev 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 @@ -601,6 +602,10 @@ sub cleanup_and_exit { d("Cleanup: Resetting forwarding sysctl to 0"); sysctl("net/ipv6/conf/all/forwarding", 0); } + if(defined($cleanup_zero_forwarding_platdev_sysctl)) { + d("Cleanup: Resetting platdev forwarding sysctl to 0"); + sysctl("net/ipv6/conf/" . $CFG{"plat-dev"} . "/forwarding", 0); + } for my $sysctl (@cleanup_accept_ra_sysctls) { d("Cleanup: Resetting $sysctl to 1"); sysctl($sysctl, 1); @@ -810,7 +815,7 @@ if(cfgbool("forwarding-enable")) { # Don't touch the ctl for the "all" interface, as that will probably # change interfaces that have accept_ra set to 0 also. next if($ctl eq "/proc/sys/net/ipv6/conf/all/accept_ra"); - + if(sysctl($ctl) == 1) { d("Changing $ctl from 1 to 2 to prevent connectivity loss after ", "enabling IPv6 forwarding"); @@ -821,6 +826,28 @@ if(cfgbool("forwarding-enable")) { sysctl("net/ipv6/conf/all/forwarding", 1); $cleanup_zero_forwarding_sysctl = 0; } + # In some scenarioes, such as a client with NetworkManager, nm will always reset + # the interface forwarding flag to 0 on a device change - the flag of 0 on a device + # always over-rides the gloabl flag of "1" on all forwarding. In this case, we need + # to always reset the flag to 1 on the plat dev. It could be the case that all forwarding + # is already set to 1, so we also here need to check the ra flag - which again, nm + # will set to 0 or 1 depending on the type of client driver in use. + if(sysctl("net/ipv6/conf/" . $CFG{"plat-dev"} . "/forwarding") == 0) { + p("Enabling IPv6 forwarding on " . $CFG{"plat-dev"}); + + # If this was already set from 1 -> 2 in the above, we'll skip due to + # the if == 1 check here, but the reset will still occur. + my $ctl = "net/ipv6/conf/" . $CFG{"plat-dev"} . "/accept_ra"; + if(sysctl($ctl) == 1) { + d("Changing $ctl from 1 to 2 to prevent connectivity loss after ", + "enabling IPv6 forwarding"); + sysctl($ctl, 2); + push(@cleanup_accept_ra_sysctls, $ctl); + } + + sysctl("net/ipv6/conf/" . $CFG{"plat-dev"} . "/forwarding", 1); + $cleanup_zero_forwarding_platdev_sysctl = 0; + } } #