Index: route.c
===================================================================
--- route.c	(revision 3956)
+++ route.c	(working copy)
@@ -214,7 +214,7 @@
     {
       goto fail;
     }
-  
+
   if (!get_special_addr (spec, ro->network, &r->network, &status))
     {
       r->network = getaddr (
@@ -371,7 +371,7 @@
       rl->spec.default_metric_defined = true;
     }
 
-  rl->spec.net_gateway_defined = get_default_gateway (&rl->spec.net_gateway, NULL);
+  rl->spec.net_gateway_defined = get_default_gateway (&rl->spec.net_gateway, NULL, rl->spec.net_gateway_ifname);
   if (rl->spec.net_gateway_defined)
     {
       setenv_route_addr (es, "net_gateway", rl->spec.net_gateway, -1);
@@ -440,6 +440,7 @@
 add_route3 (in_addr_t network,
 	    in_addr_t netmask,
 	    in_addr_t gateway,
+	    char * gateway_ifname,
 	    const struct tuntap *tt,
 	    unsigned int flags,
 	    const struct env_set *es)
@@ -450,6 +451,7 @@
   r.network = network;
   r.netmask = netmask;
   r.gateway = gateway;
+  r.gateway_ifname = gateway_ifname;
   add_route (&r, tt, flags, es);
 }
 
@@ -473,6 +475,7 @@
 static void
 add_bypass_routes (struct route_bypass *rb,
 		   in_addr_t gateway,
+		   char * gateway_ifname,
 		   const struct tuntap *tt,
 		   unsigned int flags,
 		   const struct env_set *es)
@@ -484,6 +487,7 @@
 	add_route3 (rb->bypass[i],
 		    ~0,
 		    gateway,
+		    gateway_ifname,
 		    tt,
 		    flags,
 		    es);
@@ -536,12 +540,13 @@
 	    add_route3 (rl->spec.remote_host,
 			~0,
 			rl->spec.net_gateway,
+			rl->spec.net_gateway_ifname,
 			tt,
 			flags,
 			es);
 
 	  /* route DHCP/DNS server traffic through original default gateway */
-	  add_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es);
+	  add_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, rl->spec.net_gateway_ifname, tt, flags, es);
 
 	  if (rl->flags & RG_DEF1)
 	    {
@@ -549,6 +554,7 @@
 	      add_route3 (0x00000000,
 			  0x80000000,
 			  rl->spec.remote_endpoint,
+			  NULL,
 			  tt,
 			  flags,
 			  es);
@@ -557,6 +563,7 @@
 	      add_route3 (0x80000000,
 			  0x80000000,
 			  rl->spec.remote_endpoint,
+			  NULL,
 			  tt,
 			  flags,
 			  es);
@@ -575,6 +582,7 @@
 	      add_route3 (0,
 			  0,
 			  rl->spec.remote_endpoint,
+			  NULL,
 			  tt,
 			  flags,
 			  es);
@@ -635,6 +643,7 @@
 	  add_route3 (0,
 		      0,
 		      rl->spec.net_gateway,
+		      rl->spec.net_gateway_ifname,
 		      tt,
 		      flags,
 		      es);
@@ -662,7 +671,7 @@
 				0);
 	}
 #endif
-      
+
       for (i = 0; i < rl->n; ++i)
 	{
 	  struct route *r = &rl->routes[i];
@@ -805,20 +814,26 @@
 
 #if defined(TARGET_LINUX)
 #ifdef CONFIG_FEATURE_IPROUTE
-  argv_printf (&argv, "%s route add %s/%d via %s",
+  argv_printf (&argv, "%s route add %s/%d",
   	      iproute_path,
 	      network,
-	      count_netmask_bits(netmask),
-	      gateway);
+	      count_netmask_bits(netmask));
+  if (r->gateway)
+    argv_printf_cat (&argv, "via %s", gateway);
+  else
+    argv_printf_cat (&argv, "dev %s", r->gateway_ifname);
   if (r->metric_defined)
     argv_printf_cat (&argv, "metric %d", r->metric);
 
 #else
-  argv_printf (&argv, "%s add -net %s netmask %s gw %s",
+  argv_printf (&argv, "%s add -net %s netmask %s",
 		ROUTE_PATH,
 	      network,
-	      netmask,
-	      gateway);
+	      netmask);
+  if (r->gateway)
+    argv_printf_cat (&argv, "gw %s", gateway);
+  else
+    argv_printf_cat (&argv, "dev %s", r->gateway_ifname);
   if (r->metric_defined)
     argv_printf_cat (&argv, "metric %d", r->metric);
 #endif  /*CONFIG_FEATURE_IPROUTE*/
@@ -1006,7 +1021,7 @@
   openvpn_execve_check (&argv, es, 0, "ERROR: Linux route delete command failed");
 
 #elif defined (WIN32)
-  
+
   argv_printf (&argv, "%s%sc DELETE %s MASK %s %s",
 	       get_win_sys_path(),
 	       WIN_ROUTE_PATH_SUFFIX,
@@ -1253,7 +1268,7 @@
 }
 
 bool
-get_default_gateway (in_addr_t *gw, in_addr_t *netmask)
+get_default_gateway (in_addr_t *gw, in_addr_t *netmask, char *gw_ifname)
 {
   struct gc_arena gc = gc_new ();
   bool ret_bool = false;
@@ -1328,7 +1343,7 @@
   struct gc_arena gc = gc_new ();
   bool ret = false;
   DWORD status;
-  const DWORD if_index = windows_route_find_if_index (r, tt);  
+  const DWORD if_index = windows_route_find_if_index (r, tt);
 
   if (if_index != ~0)
     {
@@ -1432,7 +1447,7 @@
 format_route_entry (const MIB_IPFORWARDROW *r, struct gc_arena *gc)
 {
   struct buffer out = alloc_buf_gc (256, gc);
-  buf_printf (&out, "%s %s %s p=%d i=%d t=%d pr=%d a=%d h=%d m=%d/%d/%d/%d/%d", 
+  buf_printf (&out, "%s %s %s p=%d i=%d t=%d pr=%d a=%d h=%d m=%d/%d/%d/%d/%d",
 	      print_in_addr_t (r->dwForwardDest, IA_NET_ORDER, gc),
 	      print_in_addr_t (r->dwForwardMask, IA_NET_ORDER, gc),
 	      print_in_addr_t (r->dwForwardNextHop, IA_NET_ORDER, gc),
@@ -1475,7 +1490,7 @@
 #elif defined(TARGET_LINUX)
 
 bool
-get_default_gateway (in_addr_t *gateway, in_addr_t *netmask)
+get_default_gateway (in_addr_t *gateway, in_addr_t *netmask, char *gw_ifname)
 {
   struct gc_arena gc = gc_new ();
   bool ret = false;
@@ -1516,6 +1531,10 @@
 		  if (!net && !mask && metric < lowest_metric)
 		    {
 		      best_gw = gw;
+		      if (gw_ifname)
+			{
+			  sscanf (line, "%" IFNAME_MAXLEN_STR "s\t", gw_ifname);
+			}
 		      lowest_metric = metric;
 		      best_count = count;
 		    }
@@ -1525,7 +1544,7 @@
 	}
       fclose (fp);
 
-      if (best_gw)
+      if (best_count)
 	{
 	  *gateway = best_gw;
 	  if (netmask)
@@ -1607,12 +1626,12 @@
         ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
 
 bool
-get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
+get_default_gateway (in_addr_t *ret, in_addr_t *netmask, char *gw_ifname)
 {
   struct gc_arena gc = gc_new ();
   int s, seq, l, pid, rtm_addrs, i;
   struct sockaddr so_dst, so_mask;
-  char *cp = m_rtmsg.m_space; 
+  char *cp = m_rtmsg.m_space;
   struct sockaddr *gate = NULL, *sa;
   struct  rt_msghdr *rtm_aux;
 
@@ -1637,7 +1656,7 @@
   rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
   rtm.rtm_version = RTM_VERSION;
   rtm.rtm_seq = ++seq;
-  rtm.rtm_addrs = rtm_addrs; 
+  rtm.rtm_addrs = rtm_addrs;
 
   so_dst.sa_family = AF_INET;
   so_dst.sa_len = sizeof(struct sockaddr_in);
@@ -1662,7 +1681,7 @@
   do {
     l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
   } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
-                        
+
   close(s);
 
   rtm_aux = &rtm;
@@ -1769,12 +1788,12 @@
         ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
 
 bool
-get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
+get_default_gateway (in_addr_t *ret, in_addr_t *netmask, char *gw_ifname)
 {
   struct gc_arena gc = gc_new ();
   int s, seq, l, pid, rtm_addrs, i;
   struct sockaddr so_dst, so_mask;
-  char *cp = m_rtmsg.m_space; 
+  char *cp = m_rtmsg.m_space;
   struct sockaddr *gate = NULL, *sa;
   struct  rt_msghdr *rtm_aux;
 
@@ -1799,7 +1818,7 @@
   rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
   rtm.rtm_version = RTM_VERSION;
   rtm.rtm_seq = ++seq;
-  rtm.rtm_addrs = rtm_addrs; 
+  rtm.rtm_addrs = rtm_addrs;
 
   so_dst.sa_family = AF_INET;
   so_dst.sa_len = sizeof(struct sockaddr_in);
@@ -1824,7 +1843,7 @@
   do {
     l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
   } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
-                        
+
   close(s);
 
   rtm_aux = &rtm;
@@ -1930,13 +1949,13 @@
         ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
 
 bool
-get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
+get_default_gateway (in_addr_t *ret, in_addr_t *netmask, char *gw_ifname)
 {
   struct gc_arena gc = gc_new ();
   int s, seq, l, rtm_addrs, i;
   pid_t pid;
   struct sockaddr so_dst, so_mask;
-  char *cp = m_rtmsg.m_space; 
+  char *cp = m_rtmsg.m_space;
   struct sockaddr *gate = NULL, *sa;
   struct  rt_msghdr *rtm_aux;
 
@@ -1961,7 +1980,7 @@
   rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
   rtm.rtm_version = RTM_VERSION;
   rtm.rtm_seq = ++seq;
-  rtm.rtm_addrs = rtm_addrs; 
+  rtm.rtm_addrs = rtm_addrs;
 
   so_dst.sa_family = AF_INET;
   so_dst.sa_len = sizeof(struct sockaddr_in);
@@ -1986,7 +2005,7 @@
   do {
     l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
   } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
-                        
+
   close(s);
 
   rtm_aux = &rtm;
@@ -2034,7 +2053,7 @@
 #else
 
 bool
-get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
+get_default_gateway (in_addr_t *ret, in_addr_t *netmask, char *gw_ifname)
 {
   return false;
 }
@@ -2152,7 +2171,7 @@
   in_addr_t gwip = 0;
   bool ret = false;
 
-  if (!get_default_gateway (&gwip, NULL))
+  if (!get_default_gateway (&gwip, NULL, NULL))
     {
       msg (M_WARN, "GDGMA: get_default_gateway failed");
       goto err;
@@ -2249,7 +2268,7 @@
   DWORD a_index;
   const IP_ADAPTER_INFO *ai;
 
-  if (!get_default_gateway (&gwip, NULL))
+  if (!get_default_gateway (&gwip, NULL, NULL))
     {
       msg (M_WARN, "GDGMA: get_default_gateway failed");
       goto err;
Index: route.h
===================================================================
--- route.h	(revision 3956)
+++ route.h	(working copy)
@@ -49,6 +49,9 @@
  */
 #define ROUTE_DELETE_FIRST  4
 
+#define IFNAME_MAXLEN 32
+#define IFNAME_MAXLEN_STR "32"
+
 struct route_bypass
 {
 # define N_ROUTE_BYPASS 8
@@ -61,6 +64,7 @@
   in_addr_t remote_endpoint;
   bool remote_endpoint_defined;
   in_addr_t net_gateway;
+  char net_gateway_ifname[IFNAME_MAXLEN];
   bool net_gateway_defined;
   in_addr_t remote_host;
   bool remote_host_defined;
@@ -95,6 +99,7 @@
   in_addr_t network;
   in_addr_t netmask;
   in_addr_t gateway;
+  char * gateway_ifname;
   bool metric_defined;
   int metric;
 };
@@ -156,7 +161,7 @@
 
 bool is_special_addr (const char *addr_str);
 
-bool get_default_gateway (in_addr_t *ip, in_addr_t *netmask);
+bool get_default_gateway (in_addr_t *ip, in_addr_t *netmask, char *gw_ifname);
 
 #if AUTO_USERID
 bool get_default_gateway_mac_addr (unsigned char *macaddr);
Index: tun.c
===================================================================
--- tun.c	(revision 3956)
+++ tun.c	(working copy)
@@ -274,7 +274,7 @@
   in_addr_t lan_gw = 0;
   in_addr_t lan_netmask = 0;
 
-  if (get_default_gateway (&lan_gw, &lan_netmask))
+  if (get_default_gateway (&lan_gw, &lan_netmask, NULL))
     {
       const in_addr_t lan_network = lan_gw & lan_netmask; 
       const in_addr_t network = ip & netmask;
@@ -301,7 +301,7 @@
   in_addr_t lan_gw = 0;
   in_addr_t lan_netmask = 0;
 
-  if (get_default_gateway (&lan_gw, &lan_netmask))
+  if (get_default_gateway (&lan_gw, &lan_netmask, NULL))
     {
       const in_addr_t lan_network = lan_gw & lan_netmask; 
       if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
