int connman_inet_set_gateway_address(int index, const char *gateway);
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);
#ifdef __cplusplus
}
static int del_routes(struct gateway_data *data)
{
- const char *address;
-
if (data->vpn) {
if (data->vpn_phy_index >= 0)
connman_inet_del_host_route(data->vpn_phy_index,
data->gateway);
- address = data->vpn_ip;
+ return connman_inet_clear_gateway_address(data->index,
+ data->vpn_ip);
+ } else if (g_strcmp0(data->gateway, "0.0.0.0") == 0) {
+ return connman_inet_clear_gateway_interface(data->index);
} else {
connman_inet_del_host_route(data->index, data->gateway);
- address = data->gateway;
+ return connman_inet_clear_gateway_address(data->index,
+ data->gateway);
}
- return connman_inet_clear_gateway_address(data->index, address);
}
static void find_element(struct connman_element *element, gpointer user_data)
{
struct connman_element *element = data->element;
struct connman_service *service = NULL;
- short int ifflags;
DBG("gateway %s", data->gateway);
return;
}
- ifflags = connman_inet_ifflags(element->index);
- if (ifflags < 0) {
- connman_error("Fail to get network interface flags");
- return;
- }
-
- if (ifflags & IFF_POINTOPOINT) {
+ if (g_strcmp0(data->gateway, "0.0.0.0") == 0) {
if (connman_inet_set_gateway_interface(element->index) < 0)
return;
goto done;
for (list = gateway_list; list; list = list->next) {
struct gateway_data *data = list->data;
+
if (data->active == TRUE)
return data;
}
DBG("gateway %s", gateway);
+ /*
+ * If gateway is NULL, it's a point to point link and the default
+ * gateway is 0.0.0.0, meaning the interface.
+ */
+ if (gateway == NULL) {
+ gateway = "0.0.0.0";
+ element->ipv4.gateway = g_strdup(gateway);
+ }
+
service = __connman_element_get_service(element);
__connman_service_indicate_state(service,
CONNMAN_SERVICE_STATE_READY);
connman_element_set_enabled(element, TRUE);
- if (gateway == NULL)
- return 0;
-
active_gateway = find_active_gateway();
new_gateway = add_gateway(element->index, gateway);
return err;
}
+
+int connman_inet_clear_gateway_interface(int index)
+{
+ struct ifreq ifr;
+ struct rtentry rt;
+ struct sockaddr_in addr;
+ int sk, err;
+
+ DBG("");
+
+ 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;
+
+ 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));
+ memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
+ memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
+
+ rt.rt_dev = ifr.ifr_name;
+
+ err = ioctl(sk, SIOCDELRT, &rt);
+ if (err < 0)
+ connman_error("Removing default interface route failed (%s)",
+ strerror(errno));
+ close(sk);
+
+ return err;
+}
__connman_ipconfig_newroute(index, scope, dststr, gatewaystr);
- if (scope != RT_SCOPE_UNIVERSE || dst.s_addr != INADDR_ANY)
+ /* skip host specific routes */
+ if (scope != RT_SCOPE_UNIVERSE &&
+ !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
+ return;
+
+ if (dst.s_addr != INADDR_ANY)
return;
for (list = rtnl_list; list; list = list->next) {
__connman_ipconfig_delroute(index, scope, dststr, gatewaystr);
- if (scope != RT_SCOPE_UNIVERSE || dst.s_addr != INADDR_ANY)
+ /* skip host specific routes */
+ if (scope != RT_SCOPE_UNIVERSE &&
+ !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
+ return;
+
+ if (dst.s_addr != INADDR_ANY)
return;
for (list = rtnl_list; list; list = list->next) {