diff --git a/src/connection.c b/src/connection.c
index 293b911..54e8a8f 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -38,6 +38,9 @@
 struct gateway_data {
 	int index;
 	char *gateway;
+	struct connman_element *element;
+	unsigned int order;
+	gboolean active;
 };
 
 static GSList *gateway_list = NULL;
@@ -63,17 +66,6 @@ static struct gateway_data *find_gateway(int index, const char *gateway)
 	return NULL;
 }
 
-static void remove_gateway(int index, const char *gateway)
-{
-	struct gateway_data *data;
-
-	data = find_gateway(index, gateway);
-	if (data == NULL)
-		return;
-
-	gateway_list = g_slist_remove(gateway_list, data);
-}
-
 static int set_route(struct connman_element *element, const char *gateway)
 {
 	struct ifreq ifr;
@@ -218,114 +210,120 @@ static void emit_default_signal(struct connman_element *element)
 	g_dbus_send_message(connection, signal);
 }
 
-static void set_default(struct connman_element *element, gpointer user_data)
+static void find_element(struct connman_element *element, gpointer user_data)
 {
 	struct gateway_data *data = user_data;
 
 	DBG("element %p name %s", element, element->name);
 
-	if (element->index != data->index)
+	if (data->element != NULL)
 		return;
 
-	if (element->enabled == TRUE)
+	if (element->index != data->index)
 		return;
-
-	connman_element_set_enabled(element, TRUE);
-	emit_default_signal(element);
+	data->element = element;
 }
 
-static void del_default(struct connman_element *element, gpointer user_data)
+struct gateway_data *add_gateway(int index, const char *gateway)
 {
-	struct gateway_data *data = user_data;
-
-	DBG("element %p name %s", element, element->name);
-
-	if (element->index != data->index)
-		return;
+	struct gateway_data *data;
+	struct connman_service *service = NULL;
+	DBG("index %d, gateway %s", index, gateway);
+	data = g_try_new0(struct gateway_data, 1);
+	if (data == NULL)
+		return NULL;
 
-	if (element->enabled == FALSE)
-		return;
+	data->index = index;
+	data->gateway = g_strdup(gateway);
+	data->active = FALSE;
+	data->element = NULL;
+	__connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION,
+							find_element, data);
 
-	connman_element_set_enabled(element, FALSE);
-	emit_default_signal(element);
+	service = __connman_element_get_service(data->element);
+	data->order = __connman_service_get_order(service);
+	gateway_list = g_slist_append(gateway_list, data);
+	return data;
 }
 
-static void new_default(struct connman_element *element, gpointer user_data)
+static void connection_newgateway(int index, const char *gateway)
 {
-	struct connman_service *service;
-	const char *gateway;
-
-	DBG("element %p name %s", element, element->name);
+	struct gateway_data *data;
+	DBG("index %d gateway %s", index, gateway);
 
-	if (g_slist_length(gateway_list) > 0)
+	data = find_gateway(index, gateway);
+	if (data == NULL) {
+		DBG("gateway has not been added!");
 		return;
+	}
+	DBG("gateway actived!");
+	data->active = TRUE;
+}
 
-	connman_element_get_value(element,
-				CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &gateway);
-
-	DBG("gateway %s", gateway);
+static void set_default_gateway(struct gateway_data *data)
+{
+	struct connman_element *element = data->element;
+	struct connman_service *service = NULL;
 
-	if (gateway == NULL)
-		return;
+	DBG("gateway %s", data->gateway);
 
-	if (set_route(element, gateway) < 0)
+	if (set_route(element, data->gateway) < 0)
 		return;
 
 	service = __connman_element_get_service(element);
 	__connman_service_indicate_default(service);
-
-	connman_element_set_enabled(element, TRUE);
-	emit_default_signal(element);
 }
 
-static void connection_newgateway(int index, const char *gateway)
+static struct gateway_data *find_default_gateway(void)
 {
-	struct gateway_data *data;
-
-	DBG("index %d gateway %s", index, gateway);
-
-	data = find_gateway(index, gateway);
-	if (data != NULL)
-		return;
-
-	data = g_try_new0(struct gateway_data, 1);
-	if (data == NULL)
-		return;
+	GSList *list = NULL;
+	unsigned int pre_order = 0;
+	struct gateway_data *re = NULL;
+	for (list = gateway_list; list; list = list->next) {
+		struct gateway_data *data = list->data;
+		DBG("index %d gateway %s order %d",
+				data->index, data->gateway, data->order);
+		/*Fix Me! the service order has not be supported,
+		all the orders are 0, so the last gateway is selected*/
+		if (pre_order <= data->order) {
+			re = data;
+			pre_order = data->order;
+		}
+		re = data;
+		break;
+	}
+	DBG("default gatway:%p", re);
+	return re;
+}
 
-	data->index = index;
-	data->gateway = g_strdup(gateway);
+static void remove_gateway(struct gateway_data *data)
+{
+	DBG("gateway:%s", data->gateway);
+	gateway_list = g_slist_remove(gateway_list, data);
 
-	gateway_list = g_slist_append(gateway_list, data);
+	if (data->active == TRUE)
+		del_route(data->element, data->gateway);
 
-	__connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION,
-							set_default, data);
+	g_free(data->gateway);
+	g_free(data);
 }
 
 static void connection_delgateway(int index, const char *gateway)
 {
 	struct gateway_data *data;
-
 	DBG("index %d gateway %s", index, gateway);
 
 	data = find_gateway(index, gateway);
-	if (data == NULL)
-		return;
-
-	gateway_list = g_slist_remove(gateway_list, data);
-
-	__connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION,
-							del_default, data);
-
-	g_free(data->gateway);
-	g_free(data);
-
-	if (g_slist_length(gateway_list) > 0)
-		return;
-
-	DBG("selecting new default gateway");
-
-	__connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION,
-							new_default, NULL);
+	if (data != NULL) {
+		DBG("gateway deactived!");
+		data->active = FALSE;
+	} else
+		DBG("gateway has been removed!");
+
+	data = find_default_gateway();
+	if (data != NULL) {
+		set_default_gateway(data);
+	}
 }
 
 static struct connman_rtnl connection_rtnl = {
@@ -454,7 +452,7 @@ static void emit_connections_signal(void)
 {
 	DBusMessage *signal;
 	DBusMessageIter entry;
-
+	DBG("");
 	signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
 				CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
 	if (signal == NULL)
@@ -469,7 +467,8 @@ static void emit_connections_signal(void)
 
 static int register_interface(struct connman_element *element)
 {
-	DBG("element %p name %s", element, element->name);
+	DBG("element %p name %s path %s",
+		element, element->name, element->path);
 
 	if (g_dbus_register_interface(connection, element->path,
 					CONNMAN_CONNECTION_INTERFACE,
@@ -494,10 +493,26 @@ static void unregister_interface(struct connman_element *element)
 						CONNMAN_CONNECTION_INTERFACE);
 }
 
+static struct gateway_data *find_active_gateway(void)
+{
+	GSList *list = NULL;
+	struct gateway_data *data = NULL;
+	DBG("");
+	for (list = gateway_list; list; list = list->next) {
+		data = list->data;
+		if (data->active == TRUE)
+			return data;
+	}
+	DBG("get gateway:%p", data);
+	return data;
+}
+
 static int connection_probe(struct connman_element *element)
 {
-	struct connman_service *service;
+	struct connman_service *service = NULL;
 	const char *gateway = NULL;
+	struct gateway_data *active_gateway = NULL;
+	struct gateway_data *new_gateway = NULL;
 
 	DBG("element %p name %s", element, element->name);
 
@@ -514,33 +529,27 @@ static int connection_probe(struct connman_element *element)
 
 	if (register_interface(element) < 0)
 		return -ENODEV;
-
 	service = __connman_element_get_service(element);
 	__connman_service_indicate_state(service,
 					CONNMAN_SERVICE_STATE_READY);
+	connman_element_set_enabled(element, TRUE);
+	emit_default_signal(element);
 
 	if (gateway == NULL)
 		return 0;
 
-	if (find_gateway(element->index, gateway) != NULL) {
-		DBG("previous gateway still present");
-		goto done;
-	}
+	active_gateway = find_active_gateway();
+	new_gateway = add_gateway(element->index, gateway);
 
-	if (g_slist_length(gateway_list) > 0) {
-		DBG("default gateway already present");
+	if (active_gateway == NULL) {
+		set_default_gateway(new_gateway);
 		return 0;
 	}
 
-	if (set_route(element, gateway) < 0)
+	if (new_gateway->order >= active_gateway->order) {
+		del_route(active_gateway->element, active_gateway->gateway);
 		return 0;
-
-done:
-	service = __connman_element_get_service(element);
-	__connman_service_indicate_default(service);
-
-	connman_element_set_enabled(element, TRUE);
-	emit_default_signal(element);
+	}
 
 	return 0;
 }
@@ -549,6 +558,7 @@ static void connection_remove(struct connman_element *element)
 {
 	struct connman_service *service;
 	const char *gateway = NULL;
+	struct gateway_data *data = NULL;
 
 	DBG("element %p name %s", element, element->name);
 
@@ -556,6 +566,9 @@ static void connection_remove(struct connman_element *element)
 	__connman_service_indicate_state(service,
 					CONNMAN_SERVICE_STATE_DISCONNECT);
 
+	connman_element_set_enabled(element, FALSE);
+	emit_default_signal(element);
+
 	unregister_interface(element);
 
 	connman_element_get_value(element,
@@ -566,12 +579,11 @@ static void connection_remove(struct connman_element *element)
 	if (gateway == NULL)
 		return;
 
-	remove_gateway(element->index, gateway);
-
-	connman_element_set_enabled(element, FALSE);
-	emit_default_signal(element);
+	data = find_gateway(element->index, gateway);
+	if (data == NULL)
+		return;
 
-	del_route(element, gateway);
+	remove_gateway(data);
 }
 
 static struct connman_driver connection_driver = {
@@ -621,3 +633,31 @@ void __connman_connection_cleanup(void)
 
 	dbus_connection_unref(connection);
 }
+
+static void update_order(void)
+{
+	GSList *list = NULL;
+	struct connman_service *service = NULL;
+	for (list = gateway_list; list; list = list->next) {
+		struct gateway_data *data = list->data;
+		service = __connman_element_get_service(data->element);
+		data->order = __connman_service_get_order(service);
+	}
+}
+/**
+ * __connman_service_update_gateway:
+ *
+ * set default gateway according to services order
+ * should be called when service order is changed
+ */
+void __connman_update_gateway(void)
+{
+	struct gateway_data *active_gateway = NULL;
+	struct gateway_data *default_gateway = NULL;
+	update_order();
+
+	active_gateway = find_active_gateway();
+	default_gateway = find_default_gateway();
+	if (active_gateway != default_gateway)
+		del_route(active_gateway->element, active_gateway->gateway);
+}
diff --git a/src/connman.h b/src/connman.h
index b41c9ee..bc9f322 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -249,6 +249,8 @@ struct connman_service *__connman_service_create_from_device(struct connman_devi
 struct connman_service *__connman_service_lookup_from_network(struct connman_network *network);
 struct connman_service *__connman_service_create_from_network(struct connman_network *network);
 
+unsigned int __connman_service_get_order(struct connman_service *service);
+
 int __connman_service_set_carrier(struct connman_service *service,
 						connman_bool_t carrier);
 int __connman_service_indicate_state(struct connman_service *service,
