summary refs log tree commit diff
path: root/src/nm-ip4-config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-ip4-config.c')
-rw-r--r--src/nm-ip4-config.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index 62b41478..490296c8 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -393,10 +393,6 @@ nm_ip_config_iter_ip4_route_init (NMDedupMultiIter *ipconf_iter, const NMIP4Conf
 const NMPObject *
 _nm_ip_config_best_default_route_find_better (const NMPObject *obj_cur, const NMPObject *obj_cmp)
 {
-	int addr_family;
-	int c;
-	guint metric_cur, metric_cmp;
-
 	nm_assert (   !obj_cur
 	           || NM_IN_SET (NMP_OBJECT_GET_TYPE (obj_cur), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
 	nm_assert (   !obj_cmp
@@ -410,17 +406,20 @@ _nm_ip_config_best_default_route_find_better (const NMPObject *obj_cur, const NM
 	 * @obj_cmp is also a default route and returns the best of both. */
 	if (   obj_cmp
 	    && nm_ip_config_best_default_route_is (obj_cmp)) {
+		guint32 metric_cur, metric_cmp;
+
 		if (!obj_cur)
 			return obj_cmp;
 
-		addr_family = NMP_OBJECT_GET_CLASS (obj_cmp)->addr_family;
-		metric_cur = nm_utils_ip_route_metric_normalize (addr_family, NMP_OBJECT_CAST_IP_ROUTE (obj_cur)->metric);
-		metric_cmp = nm_utils_ip_route_metric_normalize (addr_family, NMP_OBJECT_CAST_IP_ROUTE (obj_cmp)->metric);
+		metric_cur = NMP_OBJECT_CAST_IP_ROUTE (obj_cur)->metric;
+		metric_cmp = NMP_OBJECT_CAST_IP_ROUTE (obj_cmp)->metric;
 
 		if (metric_cmp < metric_cur)
 			return obj_cmp;
 
 		if (metric_cmp == metric_cur) {
+			int c;
+
 			/* Routes have the same metric. We still want to deterministically
 			 * prefer one or the other. It's important to consistently choose one
 			 * or the other, so that the order doesn't matter how routes are added
@@ -672,6 +671,28 @@ nm_ip4_config_update_routes_metric (NMIP4Config *self, gint64 metric)
 	g_object_thaw_notify (G_OBJECT (self));
 }
 
+static void
+_add_local_route_from_addr4 (NMIP4Config *self,
+                            const NMPlatformIP4Address *addr,
+                            int ifindex)
+{
+	nm_auto_nmpobj NMPObject *r = NULL;
+	NMPlatformIP4Route *route;
+
+	r = nmp_object_new (NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
+	route = NMP_OBJECT_CAST_IP4_ROUTE (r);
+	route->ifindex = ifindex;
+	route->rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
+	route->network = addr->address;
+	route->plen = 32;
+	route->pref_src = addr->address;
+	route->table_coerced = nm_platform_route_table_coerce (RT_TABLE_LOCAL);
+	route->type_coerced = nm_platform_route_type_coerce (RTN_LOCAL);
+	route->scope_inv = nm_platform_route_scope_inv (RT_SCOPE_HOST);
+
+	_add_route (self, r, NULL, NULL);
+}
+
 void
 nm_ip4_config_add_dependent_routes (NMIP4Config *self,
                                     guint32 route_table,
@@ -708,6 +729,8 @@ nm_ip4_config_add_dependent_routes (NMIP4Config *self,
 		if (my_addr->external)
 			continue;
 
+		_add_local_route_from_addr4 (self, my_addr, ifindex);
+
 		if (_ipv4_is_zeronet (network)) {
 			/* Kernel doesn't add device-routes for destinations that
 			 * start with 0.x.y.z. Skip them. */
@@ -1002,6 +1025,7 @@ nm_ip4_config_merge_setting (NMIP4Config *self,
 	for (i = 0; i < nroutes; i++) {
 		NMIPRoute *s_route = nm_setting_ip_config_get_route (setting, i);
 		NMPlatformIP4Route route;
+		gint64 m;
 
 		if (nm_ip_route_get_family (s_route) != AF_INET) {
 			nm_assert_not_reached ();
@@ -1015,10 +1039,11 @@ nm_ip4_config_merge_setting (NMIP4Config *self,
 		nm_assert (route.plen <= 32);
 
 		nm_ip_route_get_next_hop_binary (s_route, &route.gateway);
-		if (nm_ip_route_get_metric (s_route) == -1)
+		m = nm_ip_route_get_metric (s_route);
+		if (m < 0)
 			route.metric = route_metric;
 		else
-			route.metric = nm_ip_route_get_metric (s_route);
+			route.metric = m;
 		route.rt_source = NM_IP_CONFIG_SOURCE_USER;
 
 		route.network = nm_utils_ip4_address_clear_host_address (route.network, route.plen);
@@ -1141,8 +1166,10 @@ nm_ip4_config_create_setting (const NMIP4Config *self)
 			continue;
 
 		s_route = nm_ip_route_new_binary (AF_INET,
-		                                  &route->network, route->plen,
-		                                  &route->gateway, route->metric,
+		                                  &route->network,
+		                                  route->plen,
+		                                  &route->gateway,
+		                                  route->metric,
 		                                  NULL);
 		nm_setting_ip_config_add_route (s_ip4, s_route);
 		nm_ip_route_unref (s_route);
@@ -1227,7 +1254,7 @@ nm_ip4_config_merge (NMIP4Config *dst,
 				if (default_route_metric_penalty) {
 					NMPlatformIP4Route r = *r_src;
 
-					r.metric = nm_utils_ip_route_metric_penalize (AF_INET, r.metric, default_route_metric_penalty);
+					r.metric = nm_utils_ip_route_metric_penalize (r.metric, default_route_metric_penalty);
 					_add_route (dst, NULL, &r, NULL);
 					continue;
 				}
@@ -1459,7 +1486,7 @@ nm_ip4_config_subtract (NMIP4Config *dst,
 			 * the routes. */
 			o_lookup = nmp_object_stackinit_obj (&o_lookup_copy, o_src);
 			rr = NMP_OBJECT_CAST_IP4_ROUTE (&o_lookup_copy);
-			rr->metric = nm_utils_ip_route_metric_penalize (AF_INET, rr->metric, default_route_metric_penalty);
+			rr->metric = nm_utils_ip_route_metric_penalize (rr->metric, default_route_metric_penalty);
 		} else
 			o_lookup = o_src;
 
@@ -1610,7 +1637,7 @@ _nm_ip4_config_intersect_helper (NMIP4Config *dst,
 			 * the routes. */
 			o_lookup = nmp_object_stackinit_obj (&o_lookup_copy, o_dst);
 			rr = NMP_OBJECT_CAST_IP4_ROUTE (&o_lookup_copy);
-			rr->metric = nm_utils_ip_route_metric_penalize (AF_INET, rr->metric, default_route_metric_penalty);
+			rr->metric = nm_utils_ip_route_metric_penalize (rr->metric, default_route_metric_penalty);
 		} else
 			o_lookup = o_dst;