mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-14 05:10:35 +01:00
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.
This commit is contained in:
parent
59eb21f4a9
commit
aa5b89a2ec
3 changed files with 29 additions and 33 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
guint32 masked1 = ntohl (address1) >> (32 - plen);
|
||||
guint32 masked2 = ntohl (address2) >> (32 - plen);
|
||||
/******************************************************************/
|
||||
|
||||
return masked1 == masked2;
|
||||
static gboolean
|
||||
_ipv4_is_zeronet (in_addr_t network)
|
||||
{
|
||||
/* 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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue