Skip to contentSkip to conversation

some missing pieces for 2.3_alpha2

Openvpn-devel New Gert Doering 2 participants 7 messages Jun 10, 2012 – Jun 13, 2012

lore
Share & tools
lore
#0 lore raw

Hi,

somewhat unexpectedly, I had two days of free time at my hand, and here are what I consider the last missing pieces for basic IPv6 support in 2.3_alpha2 (the route-gateway handling for IPv6), plus a bit of cleanup that crossed my way doing this.

The code changes affect Linux iproute2, Linux ifconfig, FreeBSD and MacOS X (Darwin) and have been thoroughly tested on each affected OS (t_client tests with the current "official" set but now with indirect ping for test set 4 - which didn't work on those platforms before! - and manually staring at the routes).

TAP on MacOS 5 shows some funny effects with IPv6 routes pointing to non-existant next-hops on tap interfaces, but that seems to be an operating system thing, and nothing OpenVPN can do about it. (Well:
don't install such routes, and everything works fine :) ).

This patch set basically incorporates the work that Scott Zeid sent to the list 10 months ago (<[email protected]...>), but his doesn't work - on the BSDs, you can't use "-iface <dev>" together with a gateway spec, it must be either-or. Nevertheless, thanks for this groundwork.

Please review and ACK :-)

gert

#1 lore raw

PATCH 1/5 cleanup and redefine metric handling for IPv6 routes

"no metric set" is now stored as "-1"
"metric 0" means "on-link route" (what the BSDs do) properly initialize metric value to "0" for on-link IPv6 net on BSDs

---
 src/openvpn/init.c  |    2 +-
 src/openvpn/route.c |    9 ++++-----
 src/openvpn/tun.c   |    4 ++++
 3 files changed, 9 insertions(+), 6 deletions(-)
src/openvpn/init.c +1 -1
index 61ced5d..b726b93 100644
@@ -1251,7 +1251,7 @@ do_init_route_ipv6_list (const struct options *options,
 {
   const char *gw = NULL;
   int dev = dev_type_enum (options->dev, options->dev_type);
-  int metric = 0;
+  int metric = -1;		/* no metric set */
 
   if (dev != DEV_TYPE_TUN )
     msg( M_WARN, "IPv6 routes on TAP devices are going to fail on some platforms (need gateway spec)" );	/* TODO-GERT */
src/openvpn/route.c +4 -5
index 7c25c77..aadbacc 100644
@@ -383,7 +383,6 @@ init_route_ipv6 (struct route_ipv6 *r6,
 	         const struct route_ipv6_option *r6o,
 	         const struct route_ipv6_list *rl6 )
 {
-  r6->option = r6o;
   r6->defined = false;
 
   if ( !get_ipv6_addr( r6o->prefix, &r6->network, &r6->netbits, NULL, M_WARN ))
@@ -410,7 +409,7 @@ init_route_ipv6 (struct route_ipv6 *r6,
   /* metric */
 
   r6->metric_defined = false;
-  r6->metric = 0;
+  r6->metric = -1;
   if (is_route_parm_defined (r6o->metric))
     {
       r6->metric = atoi (r6o->metric);
@@ -700,7 +699,7 @@ init_route_ipv6_list (struct route_ipv6_list *rl6,
 
   rl6->flags = opt6->flags;
 
-  if (default_metric)
+  if (default_metric >= 0 )
     {
       rl6->default_metric = default_metric;
       rl6->default_metric_defined = true;
@@ -1582,7 +1581,7 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
 	      network,
 	      r6->netbits,
 	      device);
-  if (r6->metric_defined)
+  if (r6->metric_defined && r6->metric > 0 )
     argv_printf_cat (&argv, " metric %d", r6->metric);
 
 #else
@@ -1591,7 +1590,7 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
 	      network,
 	      r6->netbits,
 	      device);
-  if (r6->metric_defined)
+  if (r6->metric_defined && r6->metric > 0 )
     argv_printf_cat (&argv, " metric %d", r6->metric);
 #endif  /*ENABLE_IPROUTE*/
   argv_msg (D_ROUTE, &argv);
src/openvpn/tun.c +4 -0
index 633150f..460684f 100644
@@ -600,6 +600,8 @@ void add_route_connected_v6_net(struct tuntap * tt,
     r6.network = tt->local_ipv6;
     r6.netbits = tt->netbits_ipv6;
     r6.gateway = tt->local_ipv6;
+    r6.metric  = 0;			/* connected route */
+    r6.metric_defined = true;
     add_route_ipv6 (&r6, tt, 0, es);
 }
 
@@ -612,6 +614,8 @@ void delete_route_connected_v6_net(struct tuntap * tt,
     r6.network = tt->local_ipv6;
     r6.netbits = tt->netbits_ipv6;
     r6.gateway = tt->local_ipv6;
+    r6.metric  = 0;			/* connected route */
+    r6.metric_defined = true;
     delete_route_ipv6 (&r6, tt, 0, es);
 }
 #endif
Signature · 1 line
1.7.3.4
#2 lore raw

PATCH 2/5 remove "*option" element in "struct route_ipv6"

In reply to Gert Doering

this used to point to the "route_ipv6_option" that created this specific route entry, but nobody ever queried this field -> dead code.

---
 src/openvpn/route.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
src/openvpn/route.h +0 -1
index c0f5f57..e63db59 100644
@@ -124,7 +124,6 @@ struct route {
 
 struct route_ipv6 {
   bool defined;
-  const struct route_ipv6_option *option;
   struct in6_addr network;
   unsigned int netbits;
   struct in6_addr gateway;
Signature · 1 line
1.7.3.4
#3 lore raw

PATCH 3/5 Remove warning about "explicit support for IPv6 tun devices is not provided for this OS" for MacOS X (because it *is*).

In reply to Gert Doering
---
 src/openvpn/tun.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
src/openvpn/tun.c +1 -1
index 460684f..1842a97 100644
@@ -2442,7 +2442,7 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
 void
 open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
-  open_tun_generic (dev, dev_type, dev_node, false, true, tt);
+  open_tun_generic (dev, dev_type, dev_node, true, true, tt);
 }
 
 void
Signature · 1 line
1.7.3.4
#4 lore raw

PATCH 4/5 Add missing pieces to IPv6 route gateway handling.

In reply to Gert Doering

OpenVPN on Linux (iproute2+ifconfig), FreeBSD and MacOS X (Darwin) normally points routes directly towards the "tun" interface, obviating the need for a gateway. For "tap" interfaces, now add gateway spec to linux route command, and replace "-iface <dev>" with gateway spec (both together do not work) on FreeBSD and MacOS X.

Also adapt "route delete" appropriately, otherwise route will not be found.

All other platforms already use the gateway address for tun and tap, because there's no way to install a route "towards an interface" there.

Remove warning about missing IPv6 route gateway handling.

---
 src/openvpn/init.c  |    3 --
 src/openvpn/route.c |   75 +++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 64 insertions(+), 14 deletions(-)
src/openvpn/init.c +0 -3
index b726b93..320edcc 100644
@@ -1253,9 +1253,6 @@ do_init_route_ipv6_list (const struct options *options,
   int dev = dev_type_enum (options->dev, options->dev_type);
   int metric = -1;		/* no metric set */
 
-  if (dev != DEV_TYPE_TUN )
-    msg( M_WARN, "IPv6 routes on TAP devices are going to fail on some platforms (need gateway spec)" );	/* TODO-GERT */
-
   gw = options->ifconfig_ipv6_remote;		/* default GW = remote end */
 #if 0					/* not yet done for IPv6 - TODO!*/
   if ( options->route_ipv6_default_gateway )		/* override? */
src/openvpn/route.c +64 -11

155 lines not on this page · raw message

Signature · 1 line
1.7.3.4
#5 lore raw

PATCH 5/5 Update TODO.IPv6 list

In reply to Gert Doering

Clarify status of each already-done item for "IPv6 payload" TODOs.

Remove TODOs from "IPv6 transport" list that have been solved in "IPv6 payload" work.

---
 TODO.IPv6 |   35 ++++++++++++++++++++++++++++-------
 1 files changed, 28 insertions(+), 7 deletions(-)
TODO.IPv6 +28 -7
index f23cce0..29d7554 100644
@@ -5,6 +5,8 @@ TODO for IPv6 payload support
     (verified for FreeBSD server, Linux/ifconfig client, problems 
     with ICMP6 neighbor solicitations from BSD not being answered by Linux)
 
+    * 2012-01-22 fixed in platform cleanup, commit 62c613d46dc495d74
+
 2.) NetBSD IPv6 support doesn't work
     ("connected" route is not auto-created, "route-ipv6" adding fails)
 
@@ -15,6 +17,8 @@ TODO for IPv6 payload support
     * fixed for configured routes, 3.1.10 *
     * missing for manual-ifconfig-connected (NetBSD, Darwin, Win32)
 
+    * 2012-06-10 - fixed somewhere in 2010
+
 4.) do "ifconfig tun0 inet6 unplumb"  or "ifconfig tun0 destroy" for
     Solaris, *BSD, ... at program termination time, to clean up leftovers
     (unless tunnel persistance is desired).
@@ -22,6 +26,8 @@ TODO for IPv6 payload support
     For Solaris, only the "ipv6 tun0" is affected, for the *BSDs all tun0
     stay around.
 
+    * 2012-06-10 - fixed in individual platform cleanups early-2012
+
 4a.) deconfigure IPv6 on tun interface on session termination, otherwise
     one could end up with something like this (on NetBSD):
 
@@ -36,11 +42,15 @@ tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
     * semi-fixed for NetBSD, 28.2.10, always do tun0 destroy / tun0 create
       before actual ifconfig -- tunnel still lingers after OpenVPN quits
 
+    * 2011-09-16 fixed in platform cleanup, commit 8ca19c014c149cf69
+
 4b.) verify this - on FreeBSD, tun0 is auto-destroyed if created by
      opening /dev/tun (and lingers if created by "ifconfig tun0 create")
 
      -> use for persistant tunnels on not-linux?
 
+    * 2012-06-10 tun interface behaviour is documented in "man tun(4)"
+
 5.) add new option "ifconfig-ipv6-push"
     (per-client static IPv6 assignment, -> radiusplugin, etc)
 
@@ -48,12 +58,17 @@ tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
 
 6.) add new option "route-ipv6-gateway"
 
+    * 2012-06-09 - decided there is no current need (but fairly trivial)
+
 7.) add "full" gateway handling for IPv6 in route.c 
     (right now, the routes are just sent down the tun interface, if the
     operating system in questions supports that, without care for the
     gateway address - which does not work for gateways that are supposed
     to point elsewhere.  Also, it doesn't work for TAP interfaces.
 
+    * 2012-06-09 use "dev tun" for tun devices, "via $gateway" for tap
+		 (and purposely do not support off-link routes)
+
 8.) full IPv6 support for TAP interfaces 
     (main issue should be routes+gateway - and testing :-) )
 
@@ -62,8 +77,16 @@ tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
 
 17:51:14.075412 fe:ab:6e:c5:53:71 > 33:33:ff:00:00:01, ethertype IPv6 (0x86dd), length 86: 2001:608:4:a053::1:0 > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has 2001:608:4:a001::1, length 32
 
+    * 2012-06-09 missing gateway support implemented
+
+8a.)
     how is iroute-via-tap supposed to work??
 
+    * 2012-06-10 - answer: not at all, OpenVPN doesn't do "iroute" in
+    tap mode - set up "route-ipv6" with gateway address = individual
+    client's tap0 address to get the per-client routes
+
+
 9.) verify that iroute-ipv6 and route-ipv6 interact in the same way as
     documented for iroute/route:
 
@@ -113,6 +136,8 @@ tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
 	  (openvpn-devel, Subject: OpenBSD)
 	- test
 
+    * 2012-02-05 platform cleanup, commit 82d4e12068774b0a6ca
+
 17.) client-option (Elwood)
 	- ignore-v6-push-options yes/no
 	- ignore-v6-route-push  ("as for IPv4 routes")
@@ -150,13 +175,15 @@ tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
 
     (problem + workaround applies both to tun and tap style devices)
 
+    * 2012-06-09 - this got fixed in one of the platform cleanups
+
 
 
 
 TODO for IPv6 transport support
 -------------------------------
 
-[ Last updated: 11-Nov-2009. ]
+[ Last updated: 10-Jun-2012. ]
 
 * All platforms:
   o mgmt console: as currently passes straight in_addr_t bits around
@@ -175,14 +202,8 @@ TODO for IPv6 transport support
     listening IPv6 must permit incoming streams from allowed IPv4 peer,
     currently you need to pass eg:  --remote ffff::1.2.3.4
 
-  o do something with multi mode learn routes, for now just ignoring
-    ipv6 addresses seems the most sensible thing to do, because there's
-    no support for intra-tunnel ipv6 stuff.
 
 * win32:
   o find out about mapped addresses, as I can't make it work
     with bound at ::1 and connect to 127.0.0.1
 
-* N/A:
-  o this is ipv6 *endpoint* support, so don't expect "ifconfig6"-like
-    support in this patch
Signature · 1 line
1.7.3.4
Acked-by Acked-by
#6 lore raw
In reply to Gert Doering
Quoted 18 lines · Gert Doering

Hi,

somewhat unexpectedly, I had two days of free time at my hand, and here are what I consider the last missing pieces for basic IPv6 support in 2.3_alpha2 (the route-gateway handling for IPv6), plus a bit of cleanup that crossed my way doing this.

The code changes affect Linux iproute2, Linux ifconfig, FreeBSD and MacOS X (Darwin) and have been thoroughly tested on each affected OS (t_client tests with the current "official" set but now with indirect ping for test set 4 - which didn't work on those platforms before! - and manually staring at the routes).

TAP on MacOS 5 shows some funny effects with IPv6 routes pointing to non-existant next-hops on tap interfaces, but that seems to be an operating system thing, and nothing OpenVPN can do about it. (Well:
don't install such routes, and everything works fine :) ).

Quoted 7 lines

This patch set basically incorporates the work that Scott Zeid sent to the list 10 months ago (<[email protected]...>), but his doesn't work - on the BSDs, you can't use "-iface <dev>" together with a gateway spec, it must be either-or. Nevertheless, thanks for this groundwork.

Please review and ACK :-)

ACK to all. Applied to master.

commit c37d9135a27b05ff9088ca6c349fca06de89444b

Author: Gert Doering <[email protected]...>
Date:   Sun Jun 10 17:41:27 2012 +0200

cleanup and redefine metric handling for IPv6 routes

"no metric set" is now stored as "-1"
"metric 0" means "on-link route" (what the BSDs do) properly initialize metric value to "0" for on-link IPv6 net on BSDs

Message-Id: [email protected]...
URL: http://article.gmane.org/gmane.network.openvpn.devel/6710

commit 3204ac73ade94fdedbed87ab92e3adb28daada88

Author: Gert Doering <[email protected]...>
Date:   Sun Jun 10 17:41:28 2012 +0200
    remove "*option" element in "struct route_ipv6"
    
    this used to point to the "route_ipv6_option" that created this specific
    route entry, but nobody ever queried this field -> dead code.
    
    Signed-off-by: Gert Doering <[email protected]...>
    Acked-by: David Sommerseth <[email protected]...>
    Message-Id: [email protected]...
    URL: http://article.gmane.org/gmane.network.openvpn.devel/6714
    Signed-off-by: David Sommerseth <[email protected]...>

commit a9af3ca44e335716c1aab46d6702cf3530e3bb73

Author: Gert Doering <[email protected]...>
Date:   Sun Jun 10 17:41:29 2012 +0200
    Remove warning about "explicit support for IPv6 tun devices is not provided for this OS" for MacOS X (because it *is*).
    
    Signed-off-by: Gert Doering <[email protected]...>
    Acked-by: David Sommerseth <[email protected]...>
    Message-Id: [email protected]...
    URL: http://article.gmane.org/gmane.network.openvpn.devel/6716
    Signed-off-by: David Sommerseth <[email protected]...>

commit ff9c39b6c9360fba14693ab5048567599ea5a38f

Author: Gert Doering <[email protected]...>
Date:   Sun Jun 10 17:41:30 2012 +0200

Add missing pieces to IPv6 route gateway handling.

OpenVPN on Linux (iproute2+ifconfig), FreeBSD and MacOS X (Darwin) normally points routes directly towards the "tun" interface, obviating the need for a gateway. For "tap" interfaces, now add gateway spec to linux route command, and replace "-iface <dev>" with gateway spec (both together do not work) on FreeBSD and MacOS X.

Also adapt "route delete" appropriately, otherwise route will not be found.

All other platforms already use the gateway address for tun and tap, because there's no way to install a route "towards an interface" there.

Message-Id: [email protected]...
URL: http://article.gmane.org/gmane.network.openvpn.devel/6712

commit fc0c29b31c6f3804a074d8436ee738b0cee8f800

Author: Gert Doering <[email protected]...>
Date:   Sun Jun 10 17:41:31 2012 +0200

Update TODO.IPv6 list

Clarify status of each already-done item for "IPv6 payload" TODOs.

Remove TODOs from "IPv6 transport" list that have been solved in "IPv6 payload" work.

kind regards,

David Sommerseth