]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Create basic infrastructure for IPv6 default gateway handling / redirection.
authorGert Doering <gert@greenie.muc.de>
Fri, 11 Sep 2015 15:33:41 +0000 (17:33 +0200)
committerGert Doering <gert@greenie.muc.de>
Tue, 15 Sep 2015 09:46:35 +0000 (11:46 +0200)
- introduce get_default_gateway_ipv6() and add stub functions with the
  implementation plan to the 4 major code blocks here (Windows,
  Linux/Android, *BSD and Solaris, "others")

- add &rgi6 to print_default_gateway(), and teach it to print v4, v6
  or both, depending on the calling environment

- unlike IPv4 (today), get_default_gateway_ipv6() is passed the actual
  target IPv6 address of the server we're looking for, so we can handle
  more complicated routing setups ("default to eth0, vpn server to ppp0")
  correctly

- consequently, --show-gateway has an optional parameter now, the
  IPv6 address to look up (for debugging)

- document --show-gateway and the extra option in openvpn.8

Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <1441985627-14822-5-git-send-email-gert@greenie.muc.de>
URL: http://article.gmane.org/gmane.network.openvpn.devel/10087

Signed-off-by: Gert Doering <gert@greenie.muc.de>
doc/openvpn.8
src/openvpn/init.c
src/openvpn/options.c
src/openvpn/route.c
src/openvpn/route.h

index 0692a8017506e65c3885467b8673dcd590b4e92d..3a0d4e0dbcf2dd2f4c8504d65ab460c21b92e2e6 100644 (file)
@@ -5616,6 +5616,15 @@ module will be queried.
 .B \-\-verb
 option can be used BEFORE this option to produce debugging information.
 .\"*********************************************************
+.SS Standalone Debug Options:
+.\"*********************************************************
+.TP
+.B \-\-show\-gateway [v6target]
+(Standalone)
+Show current IPv4 and IPv6 default gateway and interface towards the
+gateway (if the protocol in question is enabled).  If an IPv6 address
+is passed as argument, the IPv6 route for this host is reported.
+.\"*********************************************************
 .SS IPv6 Related Options
 .\"*********************************************************
 The following options exist to support IPv6 tunneling in peer-to-peer
index fe0091865bf84b6f765391d16ed07047e45b5efc..4c17905abb026ad2c71afaaf8876bab0af86317f 100644 (file)
@@ -639,8 +639,10 @@ init_static (void)
 #ifdef TEST_GET_DEFAULT_GATEWAY
   {
     struct route_gateway_info rgi;
+    struct route_ipv6_gateway_info rgi6;
     get_default_gateway(&rgi);
-    print_default_gateway(M_INFO, &rgi);
+    get_default_gateway_ipv6(&rgi6, NULL);
+    print_default_gateway(M_INFO, &rgi, &rgi6);
     return false;
   }
 #endif
index caf1394cb26329530151c72ae7dc7958fa0ad6fa..93ea4154186a6959400b729743c08ccd41af7df8 100644 (file)
@@ -4156,12 +4156,17 @@ add_option (struct options *options,
       read_config_file (options, p[1], level, file, line, msglevel, permission_mask, option_types_found, es);
     }
 #if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
-  else if (streq (p[0], "show-gateway") && !p[1])
+  else if (streq (p[0], "show-gateway") && !p[2])
     {
       struct route_gateway_info rgi;
+      struct route_ipv6_gateway_info rgi6;
+      struct in6_addr remote = IN6ADDR_ANY_INIT;
       VERIFY_PERMISSION (OPT_P_GENERAL);
+      if (p[1])
+         get_ipv6_addr (p[1], &remote, NULL, NULL, M_WARN);
       get_default_gateway(&rgi);
-      print_default_gateway(M_INFO, &rgi);
+      get_default_gateway_ipv6(&rgi6, &remote);
+      print_default_gateway(M_INFO, &rgi, &rgi6);
       openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
     }
 #endif
index 6b2af3c6f6653d777151b65a351e331ae21d45a7..3e161404c8c7b37bee5136f3ac358cc6a762d910 100644 (file)
@@ -578,7 +578,7 @@ init_route_list (struct route_list *rl,
     {
       setenv_route_addr (es, "net_gateway", rl->rgi.gateway.addr, -1);
 #if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
-      print_default_gateway (D_ROUTE, &rl->rgi);
+      print_default_gateway (D_ROUTE, &rl->rgi, NULL);
 #endif
     }
   else
@@ -1084,10 +1084,12 @@ print_route_options (const struct route_option_list *rol,
 }
 
 void
-print_default_gateway(const int msglevel, const struct route_gateway_info *rgi)
+print_default_gateway(const int msglevel,
+                     const struct route_gateway_info *rgi,
+                     const struct route_ipv6_gateway_info *rgi6)
 {
   struct gc_arena gc = gc_new ();
-  if (rgi->flags & RGI_ADDR_DEFINED)
+  if (rgi && (rgi->flags & RGI_ADDR_DEFINED))
     {
       struct buffer out = alloc_buf_gc (256, &gc);
       buf_printf (&out, "ROUTE_GATEWAY");
@@ -1108,6 +1110,28 @@ print_default_gateway(const int msglevel, const struct route_gateway_info *rgi)
        buf_printf (&out, " HWADDR=%s", format_hex_ex (rgi->hwaddr, 6, 0, 1, ":", &gc));
       msg (msglevel, "%s", BSTR (&out));
     }
+
+  if (rgi6 && (rgi6->flags & RGI_ADDR_DEFINED))
+    {
+      struct buffer out = alloc_buf_gc (256, &gc);
+      buf_printf (&out, "ROUTE6_GATEWAY");
+      if (rgi6->flags & RGI_ON_LINK)
+       buf_printf (&out, " ON_LINK");
+      else
+       buf_printf (&out, " %s", print_in6_addr (rgi6->gateway.addr_ipv6, 0, &gc));
+      if (rgi6->flags & RGI_NETMASK_DEFINED)
+       buf_printf (&out, "/%d", rgi6->gateway.netbits_ipv6);
+#ifdef WIN32
+      if (rgi6->flags & RGI_IFACE_DEFINED)
+       buf_printf (&out, " I=%u", (unsigned int)rgi6->adapter_index);
+#else
+      if (rgi6->flags & RGI_IFACE_DEFINED)
+       buf_printf (&out, " IFACE=%s", rgi6->iface);
+#endif
+      if (rgi6->flags & RGI_HWADDR_DEFINED)
+       buf_printf (&out, " HWADDR=%s", format_hex_ex (rgi6->hwaddr, 6, 0, 1, ":", &gc));
+      msg (msglevel, "%s", BSTR (&out));
+    }
   gc_free (&gc);
 }
 
@@ -2308,6 +2332,17 @@ windows_route_find_if_index (const struct route_ipv4 *r, const struct tuntap *tt
   return ret;
 }
 
+/* IPv6 implementation using GetIpForwardTable2() and dynamic linking (TBD)
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/aa814416(v=vs.85).aspx
+ */
+void
+get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
+                        struct in6_addr *dest)
+{
+    msg(D_ROUTE, "no support for get_default_gateway_ipv6() on this system (windows)");
+    CLEAR(*rgi6);
+}
+
 bool
 add_route_ipapi (const struct route_ipv4 *r, const struct tuntap *tt, DWORD adapter_index)
 {
@@ -2624,6 +2659,24 @@ get_default_gateway (struct route_gateway_info *rgi)
   gc_free (&gc);
 }
 
+/* IPv6 implementation using netlink (TBD)
+ */
+void
+get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
+                        struct in6_addr *dest)
+{
+    msg(D_ROUTE, "no support for get_default_gateway_ipv6() on this system (Linux and Android)");
+    CLEAR(*rgi6);
+    struct in6_addr g = IN6ADDR_LOOPBACK_INIT;
+
+    rgi6->flags = RGI_ADDR_DEFINED | RGI_IFACE_DEFINED | RGI_HWADDR_DEFINED |
+               RGI_NETMASK_DEFINED;
+    rgi6->gateway.addr_ipv6 = g;
+    rgi6->gateway.netbits_ipv6 = 64;
+    memcpy( rgi6->hwaddr, "\1\2\3\4\5\6", 6 );
+    strcpy( rgi6->iface, "eth1" );
+}
+
 #elif defined(TARGET_DARWIN) || defined(TARGET_SOLARIS) || \
        defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || \
        defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
@@ -2866,6 +2919,16 @@ get_default_gateway (struct route_gateway_info *rgi)
   gc_free (&gc);
 }
 
+/* BSD implementation using routing socket (as does IPv4) (TBD)
+ */
+void
+get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
+                        struct in6_addr *dest)
+{
+    msg(D_ROUTE, "no support for get_default_gateway_ipv6() on this system (BSD and OSX)");
+    CLEAR(*rgi6);
+}
+
 #undef max
 
 #else
@@ -2899,6 +2962,13 @@ get_default_gateway (struct route_gateway_info *rgi)
 {
   CLEAR(*rgi);
 }
+void
+get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
+                        struct in6_addr *dest)
+{
+    msg(D_ROUTE, "no support for get_default_gateway_ipv6() on this system");
+    CLEAR(*rgi6);
+}
 
 #endif
 
index 5ab5f98b5dfe006bcf878c00e245070c5293c74e..95cf99f9301c7e1ca858aa58ca03633252c10c43 100644 (file)
@@ -300,7 +300,11 @@ void setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6);
 bool is_special_addr (const char *addr_str);
 
 void get_default_gateway (struct route_gateway_info *rgi);
-void print_default_gateway(const int msglevel, const struct route_gateway_info *rgi);
+void get_default_gateway_ipv6 (struct route_ipv6_gateway_info *rgi,
+                               struct in6_addr *dest);
+void print_default_gateway(const int msglevel,
+                           const struct route_gateway_info *rgi,
+                           const struct route_ipv6_gateway_info *rgi6);
 
 /*
  * Test if addr is reachable via a local interface (return ILA_LOCAL),