Hi! I'm resending this patch. Originally I sent it here [1].
In short: In the diff (agains 2.1_rc15) is the solution for the old* problem of (not) detecting default gateway on linux systems if it is a device route. It was tested by one affected user (Antonis Tsolomitis, see the thread "openvpn and ppp" on the openvpn-users list). Successfully. If I forgot anything, ask. Regards, David *See mail list threads: "Redirect-gateway on dialup" <http://thread.gmane.org/gmane.network.openvpn.user/20407> "redirect-gateway + http-proxy + ppp problem" <http://thread.gmane.org/gmane.network.openvpn.user/20994> "Cannot redirect gateway after pppd connection" <http://thread.gmane.org/gmane.network.openvpn.user/23972> "openvpn and ppp" <http://thread.gmane.org/gmane.network.openvpn.user/25117> [1]: http://article.gmane.org/gmane.network.openvpn.devel/2472 The patch: diff -u -r openvpn-2.1_rc15/route.c openvpn-2.1_rc15_gwfix/route.c --- openvpn-2.1_rc15/route.c 2008-11-17 00:48:04.000000000 +0000 +++ openvpn-2.1_rc15_gwfix/route.c 2008-12-18 19:59:36.455394121 +0000 @@ -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); @@ -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*/ @@ -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; @@ -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_if_name) { struct gc_arena gc = gc_new (); bool ret = false; @@ -1516,6 +1531,10 @@ if (!net && !mask && metric < lowest_metric) { best_gw = gw; + if (gw_if_name) + { + sscanf (line, "%s\t", gw_if_name); + } lowest_metric = metric; best_count = count; } @@ -1525,7 +1544,7 @@ } fclose (fp); - if (best_gw) + if (best_count) { *gateway = best_gw; if (netmask) @@ -1607,7 +1626,7 @@ ((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_if_name) { struct gc_arena gc = gc_new (); int s, seq, l, pid, rtm_addrs, i; @@ -1769,7 +1788,7 @@ ((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_if_name) { struct gc_arena gc = gc_new (); int s, seq, l, pid, rtm_addrs, i; @@ -1930,7 +1949,7 @@ ((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_if_name) { struct gc_arena gc = gc_new (); int s, seq, l, rtm_addrs, i; @@ -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; diff -u -r openvpn-2.1_rc15/route.h openvpn-2.1_rc15_gwfix/route.h --- openvpn-2.1_rc15/route.h 2008-10-06 07:22:20.000000000 +0000 +++ openvpn-2.1_rc15_gwfix/route.h 2008-12-18 18:29:54.996393885 +0000 @@ -61,6 +61,7 @@ in_addr_t remote_endpoint; bool remote_endpoint_defined; in_addr_t net_gateway; + char net_gateway_ifname[32]; bool net_gateway_defined; in_addr_t remote_host; bool remote_host_defined; @@ -95,6 +96,7 @@ in_addr_t network; in_addr_t netmask; in_addr_t gateway; + char * gateway_ifname; bool metric_defined; int metric; }; @@ -156,7 +158,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_if_name); #if AUTO_USERID bool get_default_gateway_mac_addr (unsigned char *macaddr); diff -u -r openvpn-2.1_rc15/tun.c openvpn-2.1_rc15_gwfix/tun.c --- openvpn-2.1_rc15/tun.c 2008-11-17 00:48:04.000000000 +0000 +++ openvpn-2.1_rc15_gwfix/tun.c 2008-12-18 11:26:07.951394102 +0000 @@ -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) --------------------------------------------------------------------- http://www.nosoftwarepatents.com Innovation, not litigation ! --- David Balažic mailto:david.bala...@hermes-softlab.com HERMES Softlab http://www.hermes-softlab.com Zagrebska cesta 104 Phone: +386 2 450 8947 SI-2000 Maribor Slovenija --------------------------------------------------------------------- "Be excellent to each other." - Bill S. Preston, Esq. & "Ted" Theodore Logan ---------------------------------------------------------------------