Fix VPN issue when setting up host route
authorMohamed Abbas <mohamed.abbas@intel.com>
Thu, 4 Feb 2010 00:16:40 +0000 (16:16 -0800)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 11 Feb 2010 04:33:05 +0000 (05:33 +0100)
include/inet.h
src/connection.c
src/inet.c

index 2b9a7df..1e95ac6 100644 (file)
@@ -44,6 +44,7 @@ connman_bool_t connman_inet_is_cfg80211(int index);
 
 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress);
 int connman_inet_clear_address(int index);
+int connman_inet_add_host_route_vpn(int index, const char *gateway, const char *host);
 int connman_inet_add_host_route(int index, const char *host);
 int connman_inet_del_host_route(int index, const char *host);
 int connman_inet_set_gateway_address(int index, const char *gateway);
index 9279c37..a46c372 100644 (file)
@@ -286,8 +286,9 @@ static int connection_probe(struct connman_element *element)
        }
 
        if (new_gateway->vpn == TRUE) {
-               connman_inet_add_host_route(active_gateway->index,
-                                               active_gateway->gateway);
+               connman_inet_add_host_route_vpn(active_gateway->index,
+                                               active_gateway->gateway,
+                                               new_gateway->gateway);
 
                connman_inet_set_gateway_address(new_gateway->index,
                                                        new_gateway->gateway);
index 4e79fe8..45c3222 100644 (file)
@@ -631,6 +631,57 @@ int connman_inet_clear_address(int index)
        return 0;
 }
 
+int connman_inet_add_host_route_vpn(int index, const char *gateway, const char *host)
+{
+       struct ifreq ifr;
+       struct rtentry rt;
+       struct sockaddr_in addr;
+       int sk, err;
+
+       sk = socket(PF_INET, SOCK_DGRAM, 0);
+       if (sk < 0)
+               return -1;
+
+       memset(&ifr, 0, sizeof(ifr));
+       ifr.ifr_ifindex = index;
+
+       if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
+               close(sk);
+               return -1;
+       }
+
+       DBG("ifname %s", ifr.ifr_name);
+
+       memset(&rt, 0, sizeof(rt));
+       rt.rt_flags = RTF_UP | RTF_HOST | RTF_GATEWAY;
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sin_family = AF_INET;
+       addr.sin_addr.s_addr = inet_addr(host);
+       memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sin_family = AF_INET;
+       addr.sin_addr.s_addr = inet_addr(gateway);;
+       memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sin_family = AF_INET;
+       addr.sin_addr.s_addr = INADDR_ANY;
+       memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
+
+       rt.rt_dev = ifr.ifr_name;
+
+       err = ioctl(sk, SIOCADDRT, &rt);
+       if (err < 0)
+               connman_error("Adding host route failed (%s)",
+                                                       strerror(errno));
+
+       close(sk);
+
+       return err;
+}
+
 int connman_inet_add_host_route(int index, const char *host)
 {
        struct ifreq ifr;