summaryrefslogtreecommitdiff
path: root/src/openvpn/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/route.c')
-rw-r--r--src/openvpn/route.c88
1 files changed, 55 insertions, 33 deletions
diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index 0c93dcd..a1811f4 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -16,10 +16,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
@@ -986,11 +985,19 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, un
if (rl && rl->flags & RG_ENABLE)
{
+ bool local = rl->flags & RG_LOCAL;
+
if (!(rl->spec.flags & RTSA_REMOTE_ENDPOINT) && (rl->flags & RG_REROUTE_GW))
{
msg(M_WARN, "%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err);
}
- else if (!(rl->rgi.flags & RGI_ADDR_DEFINED))
+ /*
+ * check if a default route is defined, unless:
+ * - we are connecting to a remote host in our network
+ * - we are connecting to a non-IPv4 remote host (i.e. we use IPv6)
+ */
+ else if (!(rl->rgi.flags & RGI_ADDR_DEFINED) && !local
+ && (rl->spec.remote_host != IPV4_INVALID_ADDR))
{
msg(M_WARN, "%s Cannot read current default gateway from system", err);
}
@@ -1001,7 +1008,6 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, un
else
{
#ifndef TARGET_ANDROID
- bool local = BOOL_CAST(rl->flags & RG_LOCAL);
if (rl->flags & RG_AUTO_LOCAL)
{
const int tla = rl->spec.remote_host_local;
@@ -1066,14 +1072,13 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, un
}
else
{
- /* delete default route */
- del_route3(0,
- 0,
- rl->rgi.gateway.addr,
- tt,
- flags | ROUTE_REF_GW,
- &rl->rgi,
- es);
+ /* don't try to remove the def route if it does not exist */
+ if (rl->rgi.flags & RGI_ADDR_DEFINED)
+ {
+ /* delete default route */
+ del_route3(0, 0, rl->rgi.gateway.addr, tt,
+ flags | ROUTE_REF_GW, &rl->rgi, es);
+ }
/* add new default route */
add_route3(0,
@@ -1145,15 +1150,12 @@ undo_redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *t
flags,
&rl->rgi,
es);
-
- /* restore original default route */
- add_route3(0,
- 0,
- rl->rgi.gateway.addr,
- tt,
- flags | ROUTE_REF_GW,
- &rl->rgi,
- es);
+ /* restore original default route if there was any */
+ if (rl->rgi.flags & RGI_ADDR_DEFINED)
+ {
+ add_route3(0, 0, rl->rgi.gateway.addr, tt,
+ flags | ROUTE_REF_GW, &rl->rgi, es);
+ }
}
}
@@ -1196,6 +1198,15 @@ add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tunt
if (rl6 && !(rl6->iflags & RL_ROUTES_ADDED) )
{
struct route_ipv6 *r;
+
+ if (!tt->did_ifconfig_ipv6_setup)
+ {
+ msg(M_INFO, "WARNING: OpenVPN was configured to add an IPv6 "
+ "route over %s. However, no IPv6 has been configured for "
+ "this interface, therefore the route installation may "
+ "fail or may not work as expected.", tt->actual_name);
+ }
+
for (r = rl6->routes_ipv6; r; r = r->next)
{
if (flags & ROUTE_DELETE_FIRST)
@@ -1281,7 +1292,9 @@ print_route_options(const struct route_option_list *rol,
(rol->flags & RG_LOCAL) != 0);
}
for (ro = rol->routes; ro; ro = ro->next)
+ {
print_route_option(ro, level);
+ }
}
void
@@ -1375,7 +1388,9 @@ print_routes(const struct route_list *rl, int level)
{
struct route_ipv4 *r;
for (r = rl->routes; r; r = r->next)
+ {
print_route(r, level);
+ }
}
static void
@@ -1404,7 +1419,9 @@ setenv_routes(struct env_set *es, const struct route_list *rl)
int i = 1;
struct route_ipv4 *r;
for (r = rl->routes; r; r = r->next)
+ {
setenv_route(es, r, i++);
+ }
}
static void
@@ -1433,7 +1450,9 @@ setenv_routes_ipv6(struct env_set *es, const struct route_ipv6_list *rl6)
int i = 1;
struct route_ipv6 *r6;
for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
+ {
setenv_route_ipv6(es, r6, i++);
+ }
}
/*
@@ -1874,14 +1893,6 @@ add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flag
}
#endif
- if (!tt->did_ifconfig_ipv6_setup)
- {
- msg( M_INFO, "add_route_ipv6(): not adding %s/%d: "
- "no IPv6 address been configured on interface %s",
- network, r6->netbits, device);
- return;
- }
-
msg( M_INFO, "add_route_ipv6(%s/%d -> %s metric %d) dev %s",
network, r6->netbits, gateway, r6->metric, device );
@@ -2623,7 +2634,9 @@ test_routes(const struct route_list *rl, const struct tuntap *tt)
{
struct route_ipv4 *r;
for (r = rl->routes, len = 0; r; r = r->next, ++len)
+ {
test_route_helper(&ret, &count, &good, &ambig, adapters, r->gateway);
+ }
if ((rl->flags & RG_ENABLE) && (rl->spec.flags & RTSA_REMOTE_ENDPOINT))
{
@@ -3047,8 +3060,10 @@ do_route_ipv6_service(const bool add, const struct route_ipv6 *r, const struct t
/* In TUN mode we use a special link-local address as the next hop.
* The tapdrvr knows about it and will answer neighbor discovery packets.
+ * (only do this for routes actually using the tun/tap device)
*/
- if (tt->type == DEV_TYPE_TUN)
+ if (tt->type == DEV_TYPE_TUN
+ && msg.iface.index == tt->adapter_index )
{
inet_pton(AF_INET6, "fe80::8", &msg.gateway.ipv6);
}
@@ -3581,6 +3596,9 @@ get_default_gateway(struct route_gateway_info *rgi)
rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
rtm.rtm_version = RTM_VERSION;
rtm.rtm_seq = ++seq;
+#ifdef TARGET_OPENBSD
+ rtm.rtm_tableid = getrtable();
+#endif
rtm.rtm_addrs = rtm_addrs;
so_dst.sa_family = AF_INET;
@@ -3608,7 +3626,8 @@ get_default_gateway(struct route_gateway_info *rgi)
msg(M_WARN, "GDG: problem writing to routing socket");
goto done;
}
- do {
+ do
+ {
l = read(sockfd, (char *)&m_rtmsg, sizeof(m_rtmsg));
} while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
close(sockfd);
@@ -3795,6 +3814,9 @@ get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
rtm.rtm_flags = RTF_UP;
rtm.rtm_version = RTM_VERSION;
rtm.rtm_seq = ++seq;
+#ifdef TARGET_OPENBSD
+ rtm.rtm_tableid = getrtable();
+#endif
so_dst.sin6_family = AF_INET6;
so_mask.sin6_family = AF_INET6;