]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Implement IPv6 interface config with non-/64 prefix lengths.
authorGert Doering <gert@greenie.muc.de>
Fri, 3 Feb 2012 16:11:03 +0000 (17:11 +0100)
committerDavid Sommerseth <davids@redhat.com>
Sat, 4 Feb 2012 12:16:06 +0000 (13:16 +0100)
Add "ifconfig_ipv6_netbits_parm" parameter to init_tun(), use that to
initialize tt->netbits_ipv6 (previously: always /64).  Actual interface
setup code already used tt->netbits_ipv6, so no changes needed there.

Remove restrictions on "/netbits" value for --server-ipv6 config option
(can now be /64.../112, previously had to be exactly /64).  Supporting
even smaller networks could cause problems with ipv6-pool handling and
are only allowed for explicit "ifconfig-ipv6", not for "server-ipv6".

Add /netbits to pushed "ifconfig-ipv6" values on server side (client
side always accepted this, but ignored it so far, so this does not
break compatibility).

Tested on Linux/ifconfig, Linux/iproute2 and FreeBSD 7.4

Signed-off-by: Gert Doering <gert@greenie.muc.de>
Acked-by: David Sommerseth <davids@redhat.com>
Signed-off-by: David Sommerseth <davids@redhat.com>
TODO.IPv6
helper.c
init.c
options.c
push.c
tun.c
tun.h

index 87c47b3e39cf81ada07b8f6507f9aa4e38686835..f23cce00ebd4ea2a31dcb95a6240fca1547c538d 100644 (file)
--- a/TODO.IPv6
+++ b/TODO.IPv6
@@ -77,6 +77,8 @@ tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
     of /netbits, and correctly ifconfig'ing this
     (default, if not specified: /64)
 
+    * done * 2012-02-03
+
 11.) do not add ipv6-routes if tun-ipv6 is not set - complain instead
 
      * done * 12.1.10
index c7333f6e1518cbc35caa149ebb8a5a8cbd040236..22ea652dd8813fc2a2ce45422b935df71fae565c 100644 (file)
--- a/helper.c
+++ b/helper.c
@@ -184,12 +184,14 @@ helper_client_server (struct options *o)
                print_in6_addr( add_in6_addr( o->server_network_ipv6, 1), 0, &o->gc );
        o->ifconfig_ipv6_remote = 
                print_in6_addr( add_in6_addr( o->server_network_ipv6, 2), 0, &o->gc );
+       o->ifconfig_ipv6_netbits = o->server_netbits_ipv6;
+
+       /* pool starts at "base address + 0x1000" - leave enough room */
+       ASSERT( o->server_netbits_ipv6 <= 112 );        /* want 16 bits */
 
-       /* pool starts at "base address + 0x10000" */
-       ASSERT( o->server_netbits_ipv6 < 96 );          /* want 32 bits */
        o->ifconfig_ipv6_pool_defined = true;
        o->ifconfig_ipv6_pool_base = 
-               add_in6_addr( o->server_network_ipv6, 0x10000 );
+               add_in6_addr( o->server_network_ipv6, 0x1000 );
        o->ifconfig_ipv6_pool_netbits = o->server_netbits_ipv6;
 
        o->tun_ipv6 = true;
diff --git a/init.c b/init.c
index b8cb84f74a5b087b77515b65383bfd46cc565e76..525f44126433cca50d69ee79ea53ec5df553d22a 100644 (file)
--- a/init.c
+++ b/init.c
@@ -1415,6 +1415,7 @@ do_init_tun (struct context *c)
                           c->options.ifconfig_local,
                           c->options.ifconfig_remote_netmask,
                           c->options.ifconfig_ipv6_local,
+                          c->options.ifconfig_ipv6_netbits,
                           c->options.ifconfig_ipv6_remote,
                           addr_host (&c->c1.link_socket_addr.local),
                           addr_host (&c->c1.link_socket_addr.remote),
index 0fbe3689853f43762fc2cc0f670916e7169b00f0..cb9738a0159b8e6d2aaae3efb5ebca3af9434e3f 100644 (file)
--- a/options.c
+++ b/options.c
@@ -2926,6 +2926,7 @@ options_string (const struct options *o,
                     o->ifconfig_local,
                     o->ifconfig_remote_netmask,
                     o->ifconfig_ipv6_local,
+                    o->ifconfig_ipv6_netbits,
                     o->ifconfig_ipv6_remote,
                     (in_addr_t)0,
                     (in_addr_t)0,
@@ -5396,9 +5397,9 @@ add_option (struct options *options,
          msg (msglevel, "error parsing --server-ipv6 parameter");
          goto err;
        }
-      if ( netbits != 64 )
+      if ( netbits < 64 || netbits > 112 )
        {
-         msg( msglevel, "--server-ipv6 settings: only /64 supported right now (not /%d)", netbits );
+         msg( msglevel, "--server-ipv6 settings: only /64../112 supported right now (not /%d)", netbits );
          goto err;
        }
       options->server_ipv6_defined = true;
diff --git a/push.c b/push.c
index a8ce3567f3fbfbe3241b483ebd2a8b312310b7c9..8a8779dca71b8feccc59c2aba509fa0f378df763 100644 (file)
--- a/push.c
+++ b/push.c
@@ -242,11 +242,9 @@ send_push_reply (struct context *c)
   if ( c->c2.push_ifconfig_ipv6_defined )
     {
       /* IPv6 is put into buffer first, could be lengthy */
-      /* TODO: push "/netbits" as well, to allow non-/64 subnet sizes
-       *       (needs changes in options.c, options.h, and other places)
-       */
-      buf_printf( &buf, ",ifconfig-ipv6 %s %s",
+      buf_printf( &buf, ",ifconfig-ipv6 %s/%d %s",
                    print_in6_addr( c->c2.push_ifconfig_ipv6_local, 0, &gc),
+                   c->c2.push_ifconfig_ipv6_netbits,
                    print_in6_addr( c->c2.push_ifconfig_ipv6_remote, 0, &gc) );
       if (BLEN (&buf) >= safe_cap)
        {
diff --git a/tun.c b/tun.c
index c9af168da24350ce2cbd3e949e6537ea54be82a9..1527ac8183dfb1a6f171f487ceec64da1a62c9a7 100644 (file)
--- a/tun.c
+++ b/tun.c
@@ -404,6 +404,7 @@ init_tun (const char *dev,       /* --dev option */
          const char *ifconfig_local_parm,          /* --ifconfig parm 1 */
          const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
          const char *ifconfig_ipv6_local_parm,     /* --ifconfig parm 1 IPv6 */
+         int         ifconfig_ipv6_netbits_parm,
          const char *ifconfig_ipv6_remote_parm,    /* --ifconfig parm 2 IPv6 */
          in_addr_t local_public,
          in_addr_t remote_public,
@@ -534,7 +535,7 @@ init_tun (const char *dev,       /* --dev option */
        {
          msg( M_FATAL, "init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary", ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm );
        }
-      tt->netbits_ipv6 = 64;
+      tt->netbits_ipv6 = ifconfig_ipv6_netbits_parm;
 
       /*
        * Set ifconfig parameters
@@ -548,6 +549,7 @@ init_tun (const char *dev,       /* --dev option */
       if (es)
        {
          setenv_str (es, "ifconfig_ipv6_local", ifconfig_ipv6_local);
+         setenv_int (es, "ifconfig_ipv6_netbits", tt->netbits_ipv6);
          setenv_str (es, "ifconfig_ipv6_remote", ifconfig_ipv6_remote);
        }
       tt->did_ifconfig_ipv6_setup = true;
diff --git a/tun.h b/tun.h
index f28b8d81a22ccd7fca969eba099d9f47fb7c2503..c0785dd8d9f358ba7859a186b101e82bf520272d 100644 (file)
--- a/tun.h
+++ b/tun.h
@@ -225,6 +225,7 @@ struct tuntap *init_tun (const char *dev,       /* --dev option */
                         const char *ifconfig_local_parm,          /* --ifconfig parm 1 */
                         const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
                         const char *ifconfig_ipv6_local_parm,     /* --ifconfig parm 1 / IPv6 */
+                        int ifconfig_ipv6_netbits_parm,           /* --ifconfig parm 1 / bits */
                         const char *ifconfig_ipv6_remote_parm,    /* --ifconfig parm 2 / IPv6 */
                         in_addr_t local_public,
                         in_addr_t remote_public,