summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-10-22 15:15:47 +0200
committerThomas Haller <thaller@redhat.com>2015-11-02 13:57:01 +0100
commitaa5b89a2ec8db5735925f78f3c91885a513ce51e (patch)
treebfc9575d7a31fde059d295ef8bd840443e2c9dd0
parent59eb21f4a99ab5d3612ae82e04e4543bfd5a2429 (diff)
downloadNetworkManager-aa5b89a2ec8db5735925f78f3c91885a513ce51e.tar.gz
ip4-config: let the IPv4 device route depend on the peer-address
Usually, the peer-address is the same as the local address. In case where it is not, it is the peer-address that determines the IPv4 device-route. So we must use the peer-address. Also, don't consider device-routes with the first octet of zero, just like kernel does. Also, nm_ip4_config_get_subnet_for_host() is effectively the same as nm_ip4_config_destination_is_direct(). So drop it.
-rw-r--r--src/devices/nm-device.c2
-rw-r--r--src/nm-ip4-config.c57
-rw-r--r--src/nm-ip4-config.h1
3 files changed, 28 insertions, 32 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 7338ff5ffb..9fe3d2ac71 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -3711,7 +3711,7 @@ ip4_config_merge_and_apply (NMDevice *self,
goto END_ADD_DEFAULT_ROUTE;
has_direct_route = ( gateway == 0
- || nm_ip4_config_get_subnet_for_host (composite, gateway)
+ || nm_ip4_config_destination_is_direct (composite, gateway, 32)
|| nm_ip4_config_get_direct_route_for_host (composite, gateway));
priv->default_route.v4_has = TRUE;
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index 413dec520e..5c35605d4b 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -100,13 +100,13 @@ nm_ip4_config_get_ifindex (const NMIP4Config *config)
return NM_IP4_CONFIG_GET_PRIVATE (config)->ifindex;
}
+/******************************************************************/
+
static gboolean
-same_prefix (guint32 address1, guint32 address2, int plen)
+_ipv4_is_zeronet (in_addr_t network)
{
- guint32 masked1 = ntohl (address1) >> (32 - plen);
- guint32 masked2 = ntohl (address2) >> (32 - plen);
-
- return masked1 == masked2;
+ /* Same as ipv4_is_zeronet() from kernel's include/linux/in.h. */
+ return (network & htonl(0xff000000)) == htonl(0x00000000);
}
/******************************************************************/
@@ -307,7 +307,16 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_fu
route.ifindex = ifindex;
route.source = NM_IP_CONFIG_SOURCE_KERNEL;
- route.network = nm_utils_ip4_address_clear_host_address (addr->address, addr->plen);
+
+ /* The destination network depends on the peer-address. */
+ route.network = nm_utils_ip4_address_clear_host_address (nm_platform_ip4_address_get_peer (addr), addr->plen);
+
+ if (_ipv4_is_zeronet (route.network)) {
+ /* Kernel doesn't add device-routes for destinations that
+ * start with 0.x.y.z. Skip them. */
+ continue;
+ }
+
route.plen = addr->plen;
route.pref_src = addr->address;
route.metric = default_route_metric;
@@ -1256,12 +1265,22 @@ nm_ip4_config_destination_is_direct (const NMIP4Config *config, guint32 network,
{
guint naddresses = nm_ip4_config_get_num_addresses (config);
int i;
+ in_addr_t peer_network;
for (i = 0; i < naddresses; i++) {
const NMPlatformIP4Address *item = nm_ip4_config_get_address (config, i);
- if (item->plen <= plen && same_prefix (item->address, network, item->plen))
- return TRUE;
+ if (item->plen > plen)
+ continue;
+
+ peer_network = nm_utils_ip4_address_clear_host_address (nm_platform_ip4_address_get_peer (item), item->plen);
+ if (_ipv4_is_zeronet (peer_network))
+ continue;
+
+ if (peer_network != nm_utils_ip4_address_clear_host_address (network, item->plen))
+ continue;
+
+ return TRUE;
}
return FALSE;
@@ -1554,28 +1573,6 @@ nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host
return best_route;
}
-const NMPlatformIP4Address *
-nm_ip4_config_get_subnet_for_host (const NMIP4Config *config, guint32 host)
-{
- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
- guint i;
- NMPlatformIP4Address *subnet = NULL;
-
- g_return_val_if_fail (host, NULL);
-
- for (i = 0; i < priv->addresses->len; i++) {
- NMPlatformIP4Address *item = &g_array_index (priv->addresses, NMPlatformIP4Address, i);
-
- if (subnet && subnet->plen >= item->plen)
- continue;
- if (nm_utils_ip4_address_clear_host_address (host, item->plen) != nm_utils_ip4_address_clear_host_address (item->address, item->plen))
- continue;
- subnet = item;
- }
-
- return subnet;
-}
-
/******************************************************************/
void
diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h
index 1c76b97e99..160f2246bf 100644
--- a/src/nm-ip4-config.h
+++ b/src/nm-ip4-config.h
@@ -102,7 +102,6 @@ guint32 nm_ip4_config_get_num_routes (const NMIP4Config *config);
const NMPlatformIP4Route *nm_ip4_config_get_route (const NMIP4Config *config, guint32 i);
const NMPlatformIP4Route *nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host);
-const NMPlatformIP4Address *nm_ip4_config_get_subnet_for_host (const NMIP4Config *config, guint32 host);
/* Nameservers */
void nm_ip4_config_reset_nameservers (NMIP4Config *config);