+ service = connman_service_get_default();
+ if (!service)
+ return NULL;
+
+ return g_hash_table_lookup(gateway_hash, service);
+}
+
+static bool choose_default_gateway(struct gateway_data *data,
+ struct gateway_data *candidate)
+{
+ bool downgraded = false;
+
+ /*
+ * If the current default is not active, then we mark
+ * this one as default. If the other one is already active
+ * we mark this one as non default.
+ */
+ if (data->ipv4_gateway && candidate->ipv4_gateway) {
+
+ if (!candidate->ipv4_gateway->active) {
+ DBG("ipv4 downgrading %p", candidate);
+ unset_default_gateway(candidate,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ }
+
+ if (candidate->ipv4_gateway->active &&
+ __connman_service_compare(candidate->service,
+ data->service) < 0) {
+ DBG("ipv4 downgrading this %p", data);
+ unset_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4);
+ downgraded = true;
+ }
+ }
+
+ if (data->ipv6_gateway && candidate->ipv6_gateway) {
+ if (!candidate->ipv6_gateway->active) {
+ DBG("ipv6 downgrading %p", candidate);
+ unset_default_gateway(candidate,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+ }
+
+ if (candidate->ipv6_gateway->active &&
+ __connman_service_compare(candidate->service,
+ data->service) < 0) {
+ DBG("ipv6 downgrading this %p", data);
+ unset_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV6);
+ downgraded = true;
+ }
+ }
+
+ return downgraded;
+}
+
+static void connection_newgateway(int index, const char *gateway)
+{
+ struct gateway_config *config;
+ struct gateway_data *data;
+ GHashTableIter iter;
+ gpointer value, key;
+ bool found = false;
+
+ DBG("index %d gateway %s", index, gateway);
+
+ config = find_gateway(index, gateway);
+ if (!config)
+ return;
+
+ config->active = true;
+
+ /*
+ * It is possible that we have two default routes atm
+ * if there are two gateways waiting rtnl activation at the
+ * same time.
+ */
+ data = lookup_gateway_data(config);
+ if (!data)
+ return;
+
+ if (data->default_checked)
+ return;
+
+ /*
+ * The next checks are only done once, otherwise setting
+ * the default gateway could lead into rtnl forever loop.
+ */
+
+ g_hash_table_iter_init(&iter, gateway_hash);
+
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ struct gateway_data *candidate = value;