Commit 63a3ecdd authored by Santtu Lakkala's avatar Santtu Lakkala

[connman] Don't add route to local VPN server. Contributes to: JB#44611

parent 4586acf9
......@@ -50,6 +50,7 @@ int connman_inet_clear_gateway_address(int index, const char *gateway);
int connman_inet_set_gateway_interface(int index);
int connman_inet_clear_gateway_interface(int index);
bool connman_inet_compare_subnet(int index, const char *host);
bool connman_inet_compare_v6_subnet(int index, const char *host);
int connman_inet_set_ipv6_address(int index,
struct connman_ipaddress *ipaddress);
int connman_inet_clear_ipv6_address(int index,
......
......@@ -244,6 +244,15 @@ static void set_vpn_routes(struct gateway_data *new_gateway,
if (!active_gateway->ipv4_gateway)
return;
/*
* If VPN server is on same subnet as we are, skip adding
* route.
*/
if (connman_inet_compare_subnet(active_gateway->index,
gateway))
return;
DBG("active gw %s", active_gateway->ipv4_gateway->gateway);
if (g_strcmp0(active_gateway->ipv4_gateway->gateway,
......@@ -260,6 +269,10 @@ static void set_vpn_routes(struct gateway_data *new_gateway,
if (!active_gateway->ipv6_gateway)
return;
if (connman_inet_compare_v6_subnet(active_gateway->index,
gateway))
return;
DBG("active gw %s", active_gateway->ipv6_gateway->gateway);
if (g_strcmp0(active_gateway->ipv6_gateway->gateway,
......
......@@ -1087,6 +1087,65 @@ bool connman_inet_compare_subnet(int index, const char *host)
return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
}
static bool mem_mask_cmp(const void *a, const void *b,
const void *mask, size_t n)
{
size_t i;
for (i = 0; i < n; i++) {
if ((((unsigned char *)a)[i] ^ ((unsigned char *)b)[i]) &
((unsigned char *)mask)[i])
return false;
}
return true;
}
bool connman_inet_compare_v6_subnet(int index, const char *host)
{
struct ifaddrs *ifaddr, *ifa;
bool rv = false;
char name[IF_NAMESIZE];
struct in6_addr haddr;
if (inet_pton(AF_INET6, host, &haddr) <= 0)
return false;
if (!if_indextoname(index, name))
return false;
DBG("index %d interface %s", index, name);
if (getifaddrs(&ifaddr) < 0) {
DBG("Cannot get addresses err %d/%s", errno, strerror(errno));
return false;
}
for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
struct sockaddr_in6 *iaddr;
struct sockaddr_in6 *imask;
if (!ifa->ifa_addr)
continue;
if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) != 0 ||
ifa->ifa_addr->sa_family != AF_INET6)
continue;
iaddr = (struct sockaddr_in6 *)ifa->ifa_addr;
imask = (struct sockaddr_in6 *)ifa->ifa_netmask;
rv = mem_mask_cmp(&iaddr->sin6_addr, &haddr,
&imask->sin6_addr,
sizeof(haddr));
goto out;
}
out:
freeifaddrs(ifaddr);
return rv;
}
int connman_inet_remove_from_bridge(int index, const char *bridge)
{
struct ifreq ifr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment