Skip to contentSkip to conversation

Del ipv6 addr on close of linux tun interface

PATCH In review Holger Kummert 2 participants 10 messages Jun 25, 2015 – Jun 26, 2015

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Del ipv6 addr on close of linux tun interface

When a linux tun interface is closed (e.g. on disconnect)
an optional ipv6 addr that was previously set is deleted now. Without this patch a later reconnect would fail with
'Linux ip -6 addr add failed: external program exited with error status: 2' and openvpn would exit.

---
 src/openvpn/tun.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
src/openvpn/tun.c +26 -0
old mode 100644
new mode 100755
index ba4b15e..8a2bccc
@@ -1687,6 +1687,32 @@ close_tun (struct tuntap *tt)
 	    argv_msg (M_INFO, &argv);
 	    openvpn_execve_check (&argv, NULL, 0, "Linux ip addr del failed");
 
+            if (tt->ipv6 && tt->did_ifconfig_ipv6_setup)
+              {
+                const char * ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
+
+#ifdef ENABLE_IPROUTE
+                argv_printf (&argv, "%s -6 addr del %s/%d dev %s",
+                                    iproute_path,
+                                    ifconfig_ipv6_local,
+                                    tt->netbits_ipv6,
+                                    tt->actual_name
+                                    );
+                argv_msg (M_INFO, &argv);
+                openvpn_execve_check (&argv, NULL, 0, "Linux ip -6 addr del failed");
+#else
+                argv_printf (&argv,
+                            "%s %s del %s/%d",
+                            IFCONFIG_PATH,
+                            tt->actual_name,
+                            ifconfig_ipv6_local,
+                            tt->netbits_ipv6
+                            );
+                argv_msg (M_INFO, &argv);
+                openvpn_execve_check (&argv, NULL, 0, "Linux ifconfig inet6 del failed");
+#endif
+              }
+
 	    argv_reset (&argv);
 	    gc_free (&gc);
 	  }
Signature · 1 line
tg: (b8ae847..) c/0007/del_ipv6_on_close (depends on: c/0006/override_common_name)
#1 lore raw

Hi,

Quoted 5 lines · Holger Kummert

When a linux tun interface is closed (e.g. on disconnect)
an optional ipv6 addr that was previously set is deleted now. Without this patch a later reconnect would fail with
'Linux ip -6 addr add failed: external program exited with error status: 2' and openvpn would exit.

There is a trac ticket to that extent already (trac #141,
http://community.openvpn.net/openvpn/ticket/141) - so thanks for the patch :-)

I'm not sure I fully understand that usage scenario - which is one of the reasons why that ticket did not proceed.

If you use normal nonpersistant tun interfaces, openvpn will destroy the tun interface at exit, removing the IPv6 address in the process.

If you use *persistant* tun interfaces, this is usually done for a reason, like "bind (nameserver) cannot bind to new interface addresses because it is running without privileges" - but in this case, we should not remove the address (because then it's gone...) - and arguably not add it either, because it should already be there - because if not, the argument with "other software needs this address" is moot.

So - help me understand the scenario. Why are you using persistant tun interfaces but want dynamically added and removed addresses?

(I can see that OpenVPN misbehaves but I'm not sure I understand what "the best" solution should be - maybe go for "if that address is already there, do not touch it, otherwise, remove existing address and add new one" instead?)

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#2 lore raw

Hello Gert,

Am 26.06.2015 um 09:35 schrieb Gert Doering:

Quoted 27 lines

Hi,

Quoted 5 lines · Holger Kummert

When a linux tun interface is closed (e.g. on disconnect)
an optional ipv6 addr that was previously set is deleted now. Without this patch a later reconnect would fail with
'Linux ip -6 addr add failed: external program exited with error status: 2' and openvpn would exit.

There is a trac ticket to that extent already (trac #141,
http://community.openvpn.net/openvpn/ticket/141) - so thanks for the patch :-)

I'm not sure I fully understand that usage scenario - which is one of the reasons why that ticket did not proceed.

If you use normal nonpersistant tun interfaces, openvpn will destroy the tun interface at exit, removing the IPv6 address in the process.

If you use *persistant* tun interfaces, this is usually done for a reason, like "bind (nameserver) cannot bind to new interface addresses because it is running without privileges" - but in this case, we should not remove the address (because then it's gone...) - and arguably not add it either, because it should already be there - because if not, the argument with "other software needs this address" is moot.

Quoted 2 lines

So - help me understand the scenario. Why are you using persistant tun interfaces but want dynamically added and removed addresses?

well, I pass the device name on the command line of the call of openvpn because I need explicit named tun-devices for firewalling purposes (the firewall on the system also needs to know the name of the device in use). So it's created on start of openvpn.
After exiting openvpn the device will be brought down.

There are no additional services depending on the tun device except the firewall which is in charge for the device only if the tunnel is established.

So the tun device is merely used like a dynamic one, but with a fixed name.

Quoted 5 lines

(I can see that OpenVPN misbehaves but I'm not sure I understand what "the best" solution should be - maybe go for "if that address is already there, do not touch it, otherwise, remove existing address and add new one" instead?)

Your proposal would probably also do the job. I didn't dive deeply into the dependencies
but just adjusted the behavior of handling ipv6 addresses to the handling of ipv4 addresses on the device.

With the provided patch the handling is at least symmetric for ipv4 and ipv6 and works in the described case (and would also work for the setup as described in trac #141).

Best regards,
Holger

Quoted 3 lines

gert

#3 lore raw

Hi,

Quoted 10 lines · Holger Kummert
Quoted 2 lines

So - help me understand the scenario. Why are you using persistant tun interfaces but want dynamically added and removed addresses?

well, I pass the device name on the command line of the call of openvpn because I need explicit named tun-devices for firewalling purposes (the firewall on the system also needs to know the name of the device in use).
So it's created on start of openvpn.
After exiting openvpn the device will be brought down.

Quoted 5 lines

There are no additional services depending on the tun device except the firewall which is in charge for the device only if the tunnel is established.

So the tun device is merely used like a dynamic one, but with a fixed name.

Mmmh. Now I am even more confused.

I assumed you were using persistant tuns because "just" using a named tunnel ("--dev tun3") should not cause this issue - as the addresses should nicely go away when the tun3 device is closed and the system destroys it...

And I actually *do* test for this in one of my t_client test runs... :-)

openvpn --client ... --nobind --comp-lzo --verb 3 --dev tun3 --proto tcp6-client --remote conn-test-server.openvpn.org --port 51194 --server-poll-timeout 10

... and it "just works" - "ip -6 addr add ... dev tun3" on connect, nothing special on disconnect, and "no problems" (on Gentoo Linux, but "ip" should be sufficiently standard):

Fri Jun 26 13:18:05 2015 /bin/ip -6 addr add fd00:abcd:194:1::100c/64 dev tun3 Fri Jun 26 13:18:05 2015 /bin/ip -6 route add fd00:abcd:194::/48 dev tun3
...
Fri Jun 26 13:18:46 2015 event_wait : Interrupted system call (code=4) Fri Jun 26 13:18:46 2015 /bin/ip route del 10.194.0.0/16
Fri Jun 26 13:18:46 2015 /bin/ip route del 10.194.1.1/32
Fri Jun 26 13:18:46 2015 delete_route_ipv6(fd00:abcd:194::/48)
Fri Jun 26 13:18:46 2015 /bin/ip -6 route del fd00:abcd:194::/48 dev tun3 Fri Jun 26 13:18:46 2015 Closing TUN/TAP interface
Fri Jun 26 13:18:46 2015 /bin/ip addr del dev tun3 local 10.194.1.54 peer 10.194.1.53

So, what is different on your end? Why is the tun<x> keeping its address?

Quoted 5 lines
Quoted 4 lines

(I can see that OpenVPN misbehaves but I'm not sure I understand what "the best" solution should be - maybe go for "if that address is already there, do not touch it, otherwise, remove existing address and add new one" instead?)

Quoted 8 lines

Your proposal would probably also do the job. I didn't dive deeply into the dependencies
but just adjusted the behavior of handling ipv6 addresses to the handling of ipv4 addresses on the device.

With the provided patch the handling is at least symmetric for ipv4 and ipv6 and works in the described
case (and would also work for the setup as described in trac #141).

Yes, your patch will make it nicely symmetric and solve the issue at hand (while my approach would need infrastructure that is totally not there today to find out "what IPv6 addresses are already configured on interface tun<X>?").

This is more wondering about what we *should* do for persistant tun interfaces... (and, now, why your tun ifs behave that way even if they are not actually persistant :) ).

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#4 lore raw

Hi,

Quoted 3 lines · Gert Doering

This is more wondering about what we *should* do for persistant tun interfaces... (and, now, why your tun ifs behave that way even if they are not actually persistant :) ).

Mulling over this for a while, I think I've come to a conclusion on "what we should do", and "what we should do in the 'persistant tun' case" (#141)

- normal case: we do "ip addr add" and "delete" - proper housekeeping, and having IPv4 and IPv6 in sync (so, Holger's patch for Linux, and possible similar additional code for all the other OSes)

- if someone really wants/needs a persistant device (created with "openvpn --mktun --dev tun3" on Linux / "ifconfig tun3 create" on *BSD), and expect it to always keep the addresses on it, they should call "openvpn --ifconfig-noexec".

This will then neither add *nor delete* the IP addresses on the interface (of course, in that case you need to run the ifconfig / ip addr statements manually before starting OpenVPN, or from an --up script which can then choose to just ignore the error if the address is already there). So this would cover the case "I want <daemon x> to listen on my tun device, but it cannot rebind if the interface goes away".

Simple and pragmatic enough?

(Having OpenVPN check addresses for persistant tun interfaces, and only add them if needed, and actually *change* them if needed would be a cool thing to have, but we have no infrastructure yet to do so)

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#5 lore raw

Hello,

Am 26.06.2015 um 16:36 schrieb Gert Doering:

Quoted 7 lines

Hi,

Quoted 3 lines · Gert Doering

This is more wondering about what we *should* do for persistant tun interfaces... (and, now, why your tun ifs behave that way even if they are not actually persistant :) ).

Quoted 7 lines

Mulling over this for a while, I think I've come to a conclusion on "what we should do", and "what we should do in the 'persistant tun' case" (#141)

- normal case: we do "ip addr add" and "delete" - proper housekeeping, and having IPv4 and IPv6 in sync (so, Holger's patch for Linux, and possible similar additional code for all the other OSes)

I looked at some other OSes in tun.c and found no other with this flaw
at a first glance (other do simply a 'destroy' or 'unplumb' of the interface). But probably I oversaw something here.

Quoted 5 lines

- if someone really wants/needs a persistant device (created with "openvpn --mktun --dev tun3" on Linux / "ifconfig tun3 create" on *BSD), and expect it to always keep the addresses on it, they should call "openvpn --ifconfig-noexec".

Yes, this sounds like a good idea to me. Had also something like "--ifconfig-notouch" in mind, but your proposal is shorter.

Quoted 10 lines

This will then neither add *nor delete* the IP addresses on the interface (of course, in that case you need to run the ifconfig / ip addr statements manually before starting OpenVPN, or from an --up script which can then choose to just ignore the error if the address is already there). So this would cover the case "I want <daemon x> to listen on my tun device, but it cannot rebind if the interface goes away".

Simple and pragmatic enough?

I second this proposal, and it would solve a long outstanding bug.

Holger

Quoted 7 lines

(Having OpenVPN check addresses for persistant tun interfaces, and only add them if needed, and actually *change* them if needed would be a cool thing to have, but we have no infrastructure yet to do so)

gert

#6 lore raw

Hi,

Quoted 11 lines · Holger Kummert
Quoted 7 lines

Mulling over this for a while, I think I've come to a conclusion on "what we should do", and "what we should do in the 'persistant tun' case" (#141)

- normal case: we do "ip addr add" and "delete" - proper housekeeping, and having IPv4 and IPv6 in sync (so, Holger's patch for Linux, and possible similar additional code for all the other OSes)

I looked at some other OSes in tun.c and found no other with this flaw at a first glance (other do simply a 'destroy' or 'unplumb' of the interface). But probably I oversaw something here.

"destroy" is only done if we actually created it - if we found the device to be "already there", we leave it alone (so that might end up with a newly acquired v6 address, then).

Quoted 7 lines
Quoted 4 lines

- if someone really wants/needs a persistant device (created with "openvpn --mktun --dev tun3" on Linux / "ifconfig tun3 create" on *BSD), and expect it to always keep the addresses on it, they should call "openvpn --ifconfig-noexec".

Yes, this sounds like a good idea to me. Had also something like "--ifconfig-notouch" in mind, but your proposal is shorter.

Since --ifconfig-noexec is already there... .-)

But I'm still interested to understand why your setup triggers this issue, and mine doesn't. The only reason I can see (really!) is that tunX has been created outside OpenVPN... - which might actually make sense if a firewall is involved, so you can tie rules to the interface right away, which won't work if the interface does not exist yet... (does it?)

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#7 lore raw
In reply to Gert Doering

Hello,

Am 26.06.2015 um 13:24 schrieb Gert Doering:

Quoted 19 lines

And I actually *do* test for this in one of my t_client test runs... :-)

openvpn --client ... --nobind --comp-lzo --verb 3 --dev tun3 --proto tcp6-client --remote conn-test-server.openvpn.org --port 51194 --server-poll-timeout 10

... and it "just works" - "ip -6 addr add ... dev tun3" on connect, nothing special on disconnect, and "no problems" (on Gentoo Linux, but "ip" should be sufficiently standard):

Fri Jun 26 13:18:05 2015 /bin/ip -6 addr add fd00:abcd:194:1::100c/64 dev tun3 Fri Jun 26 13:18:05 2015 /bin/ip -6 route add fd00:abcd:194::/48 dev tun3
...
Fri Jun 26 13:18:46 2015 event_wait : Interrupted system call (code=4) Fri Jun 26 13:18:46 2015 /bin/ip route del 10.194.0.0/16
Fri Jun 26 13:18:46 2015 /bin/ip route del 10.194.1.1/32
Fri Jun 26 13:18:46 2015 delete_route_ipv6(fd00:abcd:194::/48)
Fri Jun 26 13:18:46 2015 /bin/ip -6 route del fd00:abcd:194::/48 dev tun3 Fri Jun 26 13:18:46 2015 Closing TUN/TAP interface
Fri Jun 26 13:18:46 2015 /bin/ip addr del dev tun3 local 10.194.1.54 peer 10.194.1.53

Quoted 1 line

So, what is different on your end? Why is the tun<x> keeping its address?

This looks similar on my machine. But the difference comes when after the disconnect a new connect is forced which failed on my site.

Holger

#8 lore raw

Hi,

Quoted 4 lines · Holger Kummert
Quoted 1 line

So, what is different on your end? Why is the tun<x> keeping its address?

This looks similar on my machine. But the difference comes when after the disconnect a new connect is forced which failed on my site.

Can you send me (private mail) a log with --verb 3?

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#9 lore raw
In reply to Holger Kummert

ACK.

Your patch has been applied to the master and release/2.3 branch.

I've added a bit of text to the commit message to point to trac#141 and --ifconfig-noexec.

commit e5f71d674e3b119d6a252d7cef1c17b5c2b36a9a (master) commit 40e6c586124e6d7a764b859dad8515998c89c693 (master)

Author: Holger Kummert
Date:   Thu Jun 25 18:01:20 2015 +0200
     Del ipv6 addr on close of linux tun interface

     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/9810
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering