core/platform: add address/route sources (rh#1005416, bgo#722843)
Tag addresses and routes with their source. We'll use this later to do (or not do) operations based on where the item came from. One thing to note is that when synchronizing items with the kernel, all items are read as source=KERNEL even when they originally came from NetworkManager, since the kernel has no way of providing this source information. This requires the source 'priority', which nm_ip*_config_add_address() and nm_ip*_config_add_route() must respect to ensure that NM-owned routes don't have their source overwritten when merging various IP configs in ip*_config_merge_and_apply(). Also of note is that memcmp() can no longer be used to compare addresses/routes in nm-platform.c, but this had problems before anyway with ifindex, so that workaround from nm_platform_ip4_route_sync() can be removed. https://bugzilla.gnome.org/show_bug.cgi?id=722843 https://bugzilla.redhat.com/show_bug.cgi?id=1005416
This commit is contained in:
@@ -2310,12 +2310,14 @@ aipd_get_ip4_config (NMDevice *self, guint32 lla)
|
|||||||
memset (&address, 0, sizeof (address));
|
memset (&address, 0, sizeof (address));
|
||||||
address.address = lla;
|
address.address = lla;
|
||||||
address.plen = 16;
|
address.plen = 16;
|
||||||
|
address.source = NM_PLATFORM_SOURCE_IP4LL;
|
||||||
nm_ip4_config_add_address (config, &address);
|
nm_ip4_config_add_address (config, &address);
|
||||||
|
|
||||||
/* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */
|
/* Add a multicast route for link-local connections: destination= 224.0.0.0, netmask=240.0.0.0 */
|
||||||
memset (&route, 0, sizeof (route));
|
memset (&route, 0, sizeof (route));
|
||||||
route.network = htonl (0xE0000000L);
|
route.network = htonl (0xE0000000L);
|
||||||
route.plen = 4;
|
route.plen = 4;
|
||||||
|
route.source = NM_PLATFORM_SOURCE_IP4LL;
|
||||||
nm_ip4_config_add_route (config, &route);
|
nm_ip4_config_add_route (config, &route);
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
@@ -2834,6 +2836,7 @@ shared4_new_config (NMDevice *self, NMConnection *connection, NMDeviceStateReaso
|
|||||||
}
|
}
|
||||||
|
|
||||||
config = nm_ip4_config_new ();
|
config = nm_ip4_config_new ();
|
||||||
|
address.source = NM_PLATFORM_SOURCE_SHARED;
|
||||||
nm_ip4_config_add_address (config, &address);
|
nm_ip4_config_add_address (config, &address);
|
||||||
|
|
||||||
/* Remove the address lock when the object gets disposed */
|
/* Remove the address lock when the object gets disposed */
|
||||||
@@ -3327,6 +3330,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device
|
|||||||
address.timestamp = discovered_address->timestamp;
|
address.timestamp = discovered_address->timestamp;
|
||||||
address.lifetime = discovered_address->lifetime;
|
address.lifetime = discovered_address->lifetime;
|
||||||
address.preferred = discovered_address->preferred;
|
address.preferred = discovered_address->preferred;
|
||||||
|
address.source = NM_PLATFORM_SOURCE_RDISC;
|
||||||
|
|
||||||
nm_ip6_config_add_address (priv->ac_ip6_config, &address);
|
nm_ip6_config_add_address (priv->ac_ip6_config, &address);
|
||||||
}
|
}
|
||||||
@@ -3349,6 +3353,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device
|
|||||||
route.network = discovered_route->network;
|
route.network = discovered_route->network;
|
||||||
route.plen = discovered_route->plen;
|
route.plen = discovered_route->plen;
|
||||||
route.gateway = discovered_route->gateway;
|
route.gateway = discovered_route->gateway;
|
||||||
|
route.source = NM_PLATFORM_SOURCE_RDISC;
|
||||||
|
|
||||||
nm_ip6_config_add_route (priv->ac_ip6_config, &route);
|
nm_ip6_config_add_route (priv->ac_ip6_config, &route);
|
||||||
}
|
}
|
||||||
|
@@ -866,6 +866,7 @@ ip4_process_dhcpcd_rfc3442_routes (const char *str,
|
|||||||
route.network = rt_addr;
|
route.network = rt_addr;
|
||||||
route.plen = rt_cidr;
|
route.plen = rt_cidr;
|
||||||
route.gateway = rt_route;
|
route.gateway = rt_route;
|
||||||
|
route.source = NM_PLATFORM_SOURCE_DHCP;
|
||||||
nm_ip4_config_add_route (ip4_config, &route);
|
nm_ip4_config_add_route (ip4_config, &route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -968,6 +969,7 @@ ip4_process_dhclient_rfc3442_routes (const char *str,
|
|||||||
char addr[INET_ADDRSTRLEN];
|
char addr[INET_ADDRSTRLEN];
|
||||||
|
|
||||||
/* normal route */
|
/* normal route */
|
||||||
|
route.source = NM_PLATFORM_SOURCE_DHCP;
|
||||||
nm_ip4_config_add_route (ip4_config, &route);
|
nm_ip4_config_add_route (ip4_config, &route);
|
||||||
|
|
||||||
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s",
|
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s",
|
||||||
@@ -1087,6 +1089,7 @@ process_classful_routes (GHashTable *options, NMIP4Config *ip4_config)
|
|||||||
route.plen = 32;
|
route.plen = 32;
|
||||||
}
|
}
|
||||||
route.gateway = rt_route;
|
route.gateway = rt_route;
|
||||||
|
route.source = NM_PLATFORM_SOURCE_DHCP;
|
||||||
|
|
||||||
nm_ip4_config_add_route (ip4_config, &route);
|
nm_ip4_config_add_route (ip4_config, &route);
|
||||||
nm_log_info (LOGD_DHCP, " static route %s",
|
nm_log_info (LOGD_DHCP, " static route %s",
|
||||||
@@ -1252,6 +1255,7 @@ ip4_options_to_config (NMDHCPClient *self)
|
|||||||
nm_log_info (LOGD_DHCP4, " lease time %d", address.lifetime);
|
nm_log_info (LOGD_DHCP4, " lease time %d", address.lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
address.source = NM_PLATFORM_SOURCE_DHCP;
|
||||||
nm_ip4_config_add_address (ip4_config, &address);
|
nm_ip4_config_add_address (ip4_config, &address);
|
||||||
|
|
||||||
str = g_hash_table_lookup (priv->options, "new_host_name");
|
str = g_hash_table_lookup (priv->options, "new_host_name");
|
||||||
@@ -1419,6 +1423,7 @@ ip6_options_to_config (NMDHCPClient *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
address.address = tmp_addr;
|
address.address = tmp_addr;
|
||||||
|
address.source = NM_PLATFORM_SOURCE_DHCP;
|
||||||
nm_ip6_config_add_address (ip6_config, &address);
|
nm_ip6_config_add_address (ip6_config, &address);
|
||||||
nm_log_info (LOGD_DHCP6, " address %s", str);
|
nm_log_info (LOGD_DHCP6, " address %s", str);
|
||||||
} else if (priv->info_only == FALSE) {
|
} else if (priv->info_only == FALSE) {
|
||||||
|
@@ -625,6 +625,7 @@ nm_dhcp_dhclient_read_lease_ip_configs (const char *iface,
|
|||||||
address.plen = nm_utils_ip4_get_default_prefix (address.address);
|
address.plen = nm_utils_ip4_get_default_prefix (address.address);
|
||||||
|
|
||||||
address.lifetime = address.preferred = expiry;
|
address.lifetime = address.preferred = expiry;
|
||||||
|
address.source = NM_PLATFORM_SOURCE_DHCP;
|
||||||
|
|
||||||
ip4 = nm_ip4_config_new ();
|
ip4 = nm_ip4_config_new ();
|
||||||
nm_ip4_config_add_address (ip4, &address);
|
nm_ip4_config_add_address (ip4, &address);
|
||||||
|
@@ -656,6 +656,7 @@ static_stage3_done (NMModemBroadband *self)
|
|||||||
memset (&address, 0, sizeof (address));
|
memset (&address, 0, sizeof (address));
|
||||||
address.address = address_network;
|
address.address = address_network;
|
||||||
address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv4_config);
|
address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv4_config);
|
||||||
|
address.source = NM_PLATFORM_SOURCE_WWAN;
|
||||||
nm_ip4_config_add_address (config, &address);
|
nm_ip4_config_add_address (config, &address);
|
||||||
|
|
||||||
nm_log_info (LOGD_MB, " address %s/%d",
|
nm_log_info (LOGD_MB, " address %s/%d",
|
||||||
|
@@ -620,6 +620,7 @@ static_stage3_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
|
|||||||
/* IP address */
|
/* IP address */
|
||||||
address.address = g_value_get_uint (g_value_array_get_nth (ret_array, 0));
|
address.address = g_value_get_uint (g_value_array_get_nth (ret_array, 0));
|
||||||
address.plen = 32;
|
address.plen = 32;
|
||||||
|
address.source = NM_PLATFORM_SOURCE_WWAN;
|
||||||
nm_ip4_config_add_address (config, &address);
|
nm_ip4_config_add_address (config, &address);
|
||||||
|
|
||||||
nm_log_info (LOGD_MB, " address %s/%d",
|
nm_log_info (LOGD_MB, " address %s/%d",
|
||||||
|
@@ -335,6 +335,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting)
|
|||||||
address.plen = nm_ip4_address_get_prefix (s_addr);
|
address.plen = nm_ip4_address_get_prefix (s_addr);
|
||||||
address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
|
address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
|
||||||
address.preferred = NM_PLATFORM_LIFETIME_PERMANENT;
|
address.preferred = NM_PLATFORM_LIFETIME_PERMANENT;
|
||||||
|
address.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
|
||||||
nm_ip4_config_add_address (config, &address);
|
nm_ip4_config_add_address (config, &address);
|
||||||
}
|
}
|
||||||
@@ -351,6 +352,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting)
|
|||||||
route.plen = nm_ip4_route_get_prefix (s_route);
|
route.plen = nm_ip4_route_get_prefix (s_route);
|
||||||
route.gateway = nm_ip4_route_get_next_hop (s_route);
|
route.gateway = nm_ip4_route_get_next_hop (s_route);
|
||||||
route.metric = nm_ip4_route_get_metric (s_route);
|
route.metric = nm_ip4_route_get_metric (s_route);
|
||||||
|
route.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
|
||||||
nm_ip4_config_add_route (config, &route);
|
nm_ip4_config_add_route (config, &route);
|
||||||
}
|
}
|
||||||
@@ -981,10 +983,21 @@ nm_ip4_config_reset_addresses (NMIP4Config *config)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_ip4_config_add_address:
|
||||||
|
* @config: the #NMIP4Config
|
||||||
|
* @new: the new address to add to @config
|
||||||
|
*
|
||||||
|
* Adds the new address to @config. If an address with the same basic properties
|
||||||
|
* (address, prefix) already exists in @config, it is overwritten with the
|
||||||
|
* lifetime and preferred of @new. The source is also overwritten by the source
|
||||||
|
* from @new if that source is higher priority.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new)
|
nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new)
|
||||||
{
|
{
|
||||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||||
|
NMPlatformSource old_source;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g_return_if_fail (new != NULL);
|
g_return_if_fail (new != NULL);
|
||||||
@@ -995,7 +1008,10 @@ nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new)
|
|||||||
if (addresses_are_duplicate (item, new, FALSE)) {
|
if (addresses_are_duplicate (item, new, FALSE)) {
|
||||||
if (nm_platform_ip4_address_cmp (item, new) == 0)
|
if (nm_platform_ip4_address_cmp (item, new) == 0)
|
||||||
return;
|
return;
|
||||||
|
old_source = item->source;
|
||||||
memcpy (item, new, sizeof (*item));
|
memcpy (item, new, sizeof (*item));
|
||||||
|
/* Restore highest priority source */
|
||||||
|
item->source = MAX (old_source, new->source);
|
||||||
goto NOTIFY;
|
goto NOTIFY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1061,10 +1077,21 @@ nm_ip4_config_reset_routes (NMIP4Config *config)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_ip4_config_add_route:
|
||||||
|
* @config: the #NMIP4Config
|
||||||
|
* @new: the new route to add to @config
|
||||||
|
*
|
||||||
|
* Adds the new route to @config. If a route with the same basic properties
|
||||||
|
* (network, prefix) already exists in @config, it is overwritten including the
|
||||||
|
* gateway and metric of @new. The source is also overwritten by the source
|
||||||
|
* from @new if that source is higher priority.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new)
|
nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new)
|
||||||
{
|
{
|
||||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||||
|
NMPlatformSource old_source;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g_return_if_fail (new != NULL);
|
g_return_if_fail (new != NULL);
|
||||||
@@ -1075,7 +1102,10 @@ nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new)
|
|||||||
if (routes_are_duplicate (item, new, FALSE)) {
|
if (routes_are_duplicate (item, new, FALSE)) {
|
||||||
if (nm_platform_ip4_route_cmp (item, new) == 0)
|
if (nm_platform_ip4_route_cmp (item, new) == 0)
|
||||||
return;
|
return;
|
||||||
|
old_source = item->source;
|
||||||
memcpy (item, new, sizeof (*item));
|
memcpy (item, new, sizeof (*item));
|
||||||
|
/* Restore highest priority source */
|
||||||
|
item->source = MAX (old_source, new->source);
|
||||||
goto NOTIFY;
|
goto NOTIFY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1500,6 +1530,19 @@ nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_ip4_config_equal:
|
||||||
|
* @a: first config to compare
|
||||||
|
* @b: second config to compare
|
||||||
|
*
|
||||||
|
* Compares two #NMIP4Configs for basic equality. This means that all
|
||||||
|
* attributes must exist in the same order in both configs (addresses, routes,
|
||||||
|
* domains, DNS servers, etc) but some attributes (address lifetimes, and address
|
||||||
|
* and route sources) are ignored.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the configurations are basically equal to each other,
|
||||||
|
* %FALSE if not
|
||||||
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
nm_ip4_config_equal (const NMIP4Config *a, const NMIP4Config *b)
|
nm_ip4_config_equal (const NMIP4Config *a, const NMIP4Config *b)
|
||||||
{
|
{
|
||||||
|
@@ -330,6 +330,7 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIP6Config *setting)
|
|||||||
address.plen = nm_ip6_address_get_prefix (s_addr);
|
address.plen = nm_ip6_address_get_prefix (s_addr);
|
||||||
address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
|
address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
|
||||||
address.preferred = NM_PLATFORM_LIFETIME_PERMANENT;
|
address.preferred = NM_PLATFORM_LIFETIME_PERMANENT;
|
||||||
|
address.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
|
||||||
nm_ip6_config_add_address (config, &address);
|
nm_ip6_config_add_address (config, &address);
|
||||||
}
|
}
|
||||||
@@ -346,6 +347,7 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIP6Config *setting)
|
|||||||
route.plen = nm_ip6_route_get_prefix (s_route);
|
route.plen = nm_ip6_route_get_prefix (s_route);
|
||||||
route.gateway = *nm_ip6_route_get_next_hop (s_route);
|
route.gateway = *nm_ip6_route_get_next_hop (s_route);
|
||||||
route.metric = nm_ip6_route_get_metric (s_route);
|
route.metric = nm_ip6_route_get_metric (s_route);
|
||||||
|
route.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
|
||||||
nm_ip6_config_add_route (config, &route);
|
nm_ip6_config_add_route (config, &route);
|
||||||
}
|
}
|
||||||
@@ -887,10 +889,21 @@ nm_ip6_config_reset_addresses (NMIP6Config *config)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_ip6_config_add_address:
|
||||||
|
* @config: the #NMIP6Config
|
||||||
|
* @new: the new address to add to @config
|
||||||
|
*
|
||||||
|
* Adds the new address to @config. If an address with the same basic properties
|
||||||
|
* (address, prefix) already exists in @config, it is overwritten with the
|
||||||
|
* lifetime and preferred of @new. The source is also overwritten by the source
|
||||||
|
* from @new if that source is higher priority.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new)
|
nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new)
|
||||||
{
|
{
|
||||||
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
|
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
|
||||||
|
NMPlatformSource old_source;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g_return_if_fail (new != NULL);
|
g_return_if_fail (new != NULL);
|
||||||
@@ -901,8 +914,11 @@ nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new)
|
|||||||
if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) {
|
if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) {
|
||||||
if (nm_platform_ip6_address_cmp (item, new) == 0)
|
if (nm_platform_ip6_address_cmp (item, new) == 0)
|
||||||
return;
|
return;
|
||||||
|
old_source = item->source;
|
||||||
/* Copy over old item to get new lifetime, timestamp, preferred */
|
/* Copy over old item to get new lifetime, timestamp, preferred */
|
||||||
*item = *new;
|
*item = *new;
|
||||||
|
/* But restore highest priority source */
|
||||||
|
item->source = MAX (old_source, new->source);
|
||||||
goto NOTIFY;
|
goto NOTIFY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -969,10 +985,21 @@ nm_ip6_config_reset_routes (NMIP6Config *config)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_ip6_config_add_route:
|
||||||
|
* @config: the #NMIP6Config
|
||||||
|
* @new: the new route to add to @config
|
||||||
|
*
|
||||||
|
* Adds the new route to @config. If a route with the same basic properties
|
||||||
|
* (network, prefix) already exists in @config, it is overwritten including the
|
||||||
|
* gateway and metric of @new. The source is also overwritten by the source
|
||||||
|
* from @new if that source is higher priority.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new)
|
nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new)
|
||||||
{
|
{
|
||||||
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
|
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
|
||||||
|
NMPlatformSource old_source;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g_return_if_fail (new != NULL);
|
g_return_if_fail (new != NULL);
|
||||||
@@ -983,7 +1010,10 @@ nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new)
|
|||||||
if (routes_are_duplicate (item, new, FALSE)) {
|
if (routes_are_duplicate (item, new, FALSE)) {
|
||||||
if (nm_platform_ip6_route_cmp (item, new) == 0)
|
if (nm_platform_ip6_route_cmp (item, new) == 0)
|
||||||
return;
|
return;
|
||||||
|
old_source = item->source;
|
||||||
*item = *new;
|
*item = *new;
|
||||||
|
/* Restore highest priority source */
|
||||||
|
item->source = MAX (old_source, new->source);
|
||||||
goto NOTIFY;
|
goto NOTIFY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1268,6 +1298,19 @@ nm_ip6_config_hash (const NMIP6Config *config, GChecksum *sum, gboolean dns_only
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_ip6_config_equal:
|
||||||
|
* @a: first config to compare
|
||||||
|
* @b: second config to compare
|
||||||
|
*
|
||||||
|
* Compares two #NMIP6Configs for basic equality. This means that all
|
||||||
|
* attributes must exist in the same order in both configs (addresses, routes,
|
||||||
|
* domains, DNS servers, etc) but some attributes (address lifetimes, and address
|
||||||
|
* and route sources) are ignored.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the configurations are basically equal to each other,
|
||||||
|
* %FALSE if not
|
||||||
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
nm_ip6_config_equal (const NMIP6Config *a, const NMIP6Config *b)
|
nm_ip6_config_equal (const NMIP6Config *a, const NMIP6Config *b)
|
||||||
{
|
{
|
||||||
|
@@ -2196,6 +2196,7 @@ ip4_address_get_all (NMPlatform *platform, int ifindex)
|
|||||||
for (object = nl_cache_get_first (priv->address_cache); object; object = nl_cache_get_next (object)) {
|
for (object = nl_cache_get_first (priv->address_cache); object; object = nl_cache_get_next (object)) {
|
||||||
if (nl_object_is_marked (object)) {
|
if (nl_object_is_marked (object)) {
|
||||||
init_ip4_address (&address, (struct rtnl_addr *) object);
|
init_ip4_address (&address, (struct rtnl_addr *) object);
|
||||||
|
address.source = NM_PLATFORM_SOURCE_KERNEL;
|
||||||
g_array_append_val (addresses, address);
|
g_array_append_val (addresses, address);
|
||||||
nl_object_unmark (object);
|
nl_object_unmark (object);
|
||||||
}
|
}
|
||||||
@@ -2219,6 +2220,7 @@ ip6_address_get_all (NMPlatform *platform, int ifindex)
|
|||||||
for (object = nl_cache_get_first (priv->address_cache); object; object = nl_cache_get_next (object)) {
|
for (object = nl_cache_get_first (priv->address_cache); object; object = nl_cache_get_next (object)) {
|
||||||
if (nl_object_is_marked (object)) {
|
if (nl_object_is_marked (object)) {
|
||||||
init_ip6_address (&address, (struct rtnl_addr *) object);
|
init_ip6_address (&address, (struct rtnl_addr *) object);
|
||||||
|
address.source = NM_PLATFORM_SOURCE_KERNEL;
|
||||||
g_array_append_val (addresses, address);
|
g_array_append_val (addresses, address);
|
||||||
nl_object_unmark (object);
|
nl_object_unmark (object);
|
||||||
}
|
}
|
||||||
@@ -2410,6 +2412,7 @@ ip4_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default)
|
|||||||
for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) {
|
for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) {
|
||||||
if (nl_object_is_marked (object)) {
|
if (nl_object_is_marked (object)) {
|
||||||
if (init_ip4_route (&route, (struct rtnl_route *) object)) {
|
if (init_ip4_route (&route, (struct rtnl_route *) object)) {
|
||||||
|
route.source = NM_PLATFORM_SOURCE_KERNEL;
|
||||||
if (route.plen != 0 || include_default)
|
if (route.plen != 0 || include_default)
|
||||||
g_array_append_val (routes, route);
|
g_array_append_val (routes, route);
|
||||||
}
|
}
|
||||||
@@ -2435,6 +2438,7 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default)
|
|||||||
for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) {
|
for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) {
|
||||||
if (nl_object_is_marked (object)) {
|
if (nl_object_is_marked (object)) {
|
||||||
if (init_ip6_route (&route, (struct rtnl_route *) object)) {
|
if (init_ip6_route (&route, (struct rtnl_route *) object)) {
|
||||||
|
route.source = NM_PLATFORM_SOURCE_KERNEL;
|
||||||
if (route.plen != 0 || include_default)
|
if (route.plen != 0 || include_default)
|
||||||
g_array_append_val (routes, route);
|
g_array_append_val (routes, route);
|
||||||
}
|
}
|
||||||
|
@@ -1563,9 +1563,15 @@ array_contains_ip4_route (const GArray *routes, const NMPlatformIP4Route *route)
|
|||||||
guint len = routes ? routes->len : 0;
|
guint len = routes ? routes->len : 0;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++) {
|
||||||
if (!memcmp (&g_array_index (routes, NMPlatformIP4Route, i), route, sizeof (*route)))
|
NMPlatformIP4Route *c = &g_array_index (routes, NMPlatformIP4Route, i);
|
||||||
|
|
||||||
|
if (route->network == c->network &&
|
||||||
|
route->plen == c->plen &&
|
||||||
|
route->gateway == c->gateway &&
|
||||||
|
route->metric == c->metric)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1576,9 +1582,15 @@ array_contains_ip6_route (const GArray *routes, const NMPlatformIP6Route *route)
|
|||||||
guint len = routes ? routes->len : 0;
|
guint len = routes ? routes->len : 0;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++) {
|
||||||
if (!memcmp (&g_array_index (routes, NMPlatformIP6Route, i), route, sizeof (*route)))
|
NMPlatformIP6Route *c = &g_array_index (routes, NMPlatformIP6Route, i);
|
||||||
|
|
||||||
|
if (IN6_ARE_ADDR_EQUAL (&route->network, &c->network) &&
|
||||||
|
route->plen == c->plen &&
|
||||||
|
IN6_ARE_ADDR_EQUAL (&route->gateway, &c->gateway) &&
|
||||||
|
route->metric == c->metric)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1606,7 +1618,6 @@ nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes)
|
|||||||
routes = nm_platform_ip4_route_get_all (ifindex, FALSE);
|
routes = nm_platform_ip4_route_get_all (ifindex, FALSE);
|
||||||
for (i = 0; i < routes->len; i++) {
|
for (i = 0; i < routes->len; i++) {
|
||||||
route = &g_array_index (routes, NMPlatformIP4Route, i);
|
route = &g_array_index (routes, NMPlatformIP4Route, i);
|
||||||
route->ifindex = 0;
|
|
||||||
|
|
||||||
if (!array_contains_ip4_route (known_routes, route))
|
if (!array_contains_ip4_route (known_routes, route))
|
||||||
nm_platform_ip4_route_delete (ifindex, route->network, route->plen, route->metric);
|
nm_platform_ip4_route_delete (ifindex, route->network, route->plen, route->metric);
|
||||||
@@ -1684,6 +1695,34 @@ nm_platform_route_flush (int ifindex)
|
|||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
source_to_string (NMPlatformSource source)
|
||||||
|
{
|
||||||
|
switch (source) {
|
||||||
|
case NM_PLATFORM_SOURCE_KERNEL:
|
||||||
|
return "kernel";
|
||||||
|
case NM_PLATFORM_SOURCE_SHARED:
|
||||||
|
return "shared";
|
||||||
|
case NM_PLATFORM_SOURCE_IP4LL:
|
||||||
|
return "ipv4ll";
|
||||||
|
case NM_PLATFORM_SOURCE_PPP:
|
||||||
|
return "ppp";
|
||||||
|
case NM_PLATFORM_SOURCE_WWAN:
|
||||||
|
return "wwan";
|
||||||
|
case NM_PLATFORM_SOURCE_VPN:
|
||||||
|
return "vpn";
|
||||||
|
case NM_PLATFORM_SOURCE_DHCP:
|
||||||
|
return "dhcp";
|
||||||
|
case NM_PLATFORM_SOURCE_RDISC:
|
||||||
|
return "rdisc";
|
||||||
|
case NM_PLATFORM_SOURCE_USER:
|
||||||
|
return "user";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_platform_ip4_address_to_string:
|
* nm_platform_ip4_address_to_string:
|
||||||
* @route: pointer to NMPlatformIP4Address address structure
|
* @route: pointer to NMPlatformIP4Address address structure
|
||||||
@@ -1718,11 +1757,12 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address)
|
|||||||
s_dev = address->ifindex > 0 ? nm_platform_link_get_name (address->ifindex) : NULL;
|
s_dev = address->ifindex > 0 ? nm_platform_link_get_name (address->ifindex) : NULL;
|
||||||
str_dev = s_dev ? g_strconcat (" dev ", s_dev, NULL) : NULL;
|
str_dev = s_dev ? g_strconcat (" dev ", s_dev, NULL) : NULL;
|
||||||
|
|
||||||
g_snprintf (buffer, sizeof (buffer), "%s/%d lft %u pref %u time %u%s%s",
|
g_snprintf (buffer, sizeof (buffer), "%s/%d lft %u pref %u time %u%s%s src %s",
|
||||||
s_address, address->plen, (guint)address->lifetime, (guint)address->preferred,
|
s_address, address->plen, (guint)address->lifetime, (guint)address->preferred,
|
||||||
(guint)address->timestamp,
|
(guint)address->timestamp,
|
||||||
str_peer ? str_peer : "",
|
str_peer ? str_peer : "",
|
||||||
str_dev ? str_dev : "");
|
str_dev ? str_dev : "",
|
||||||
|
source_to_string (address->source));
|
||||||
g_free (str_dev);
|
g_free (str_dev);
|
||||||
g_free (str_peer);
|
g_free (str_peer);
|
||||||
return buffer;
|
return buffer;
|
||||||
@@ -1767,12 +1807,13 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address)
|
|||||||
rtnl_addr_flags2str(address->flags, s_flags, sizeof(s_flags));
|
rtnl_addr_flags2str(address->flags, s_flags, sizeof(s_flags));
|
||||||
str_flags = s_flags[0] ? g_strconcat (" flags ", s_flags, NULL) : NULL;
|
str_flags = s_flags[0] ? g_strconcat (" flags ", s_flags, NULL) : NULL;
|
||||||
|
|
||||||
g_snprintf (buffer, sizeof (buffer), "%s/%d lft %u pref %u time %u%s%s%s",
|
g_snprintf (buffer, sizeof (buffer), "%s/%d lft %u pref %u time %u%s%s%s src %s",
|
||||||
s_address, address->plen, (guint)address->lifetime, (guint)address->preferred,
|
s_address, address->plen, (guint)address->lifetime, (guint)address->preferred,
|
||||||
(guint)address->timestamp,
|
(guint)address->timestamp,
|
||||||
str_peer ? str_peer : "",
|
str_peer ? str_peer : "",
|
||||||
str_dev ? str_dev : "",
|
str_dev ? str_dev : "",
|
||||||
str_flags ? str_flags : "");
|
str_flags ? str_flags : "",
|
||||||
|
source_to_string (address->source));
|
||||||
g_free (str_flags);
|
g_free (str_flags);
|
||||||
g_free (str_dev);
|
g_free (str_dev);
|
||||||
g_free (str_peer);
|
g_free (str_peer);
|
||||||
@@ -1807,10 +1848,11 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route)
|
|||||||
s_dev = route->ifindex > 0 ? nm_platform_link_get_name (route->ifindex) : NULL;
|
s_dev = route->ifindex > 0 ? nm_platform_link_get_name (route->ifindex) : NULL;
|
||||||
str_dev = s_dev ? g_strconcat (" dev ", s_dev, NULL) : NULL;
|
str_dev = s_dev ? g_strconcat (" dev ", s_dev, NULL) : NULL;
|
||||||
|
|
||||||
g_snprintf (buffer, sizeof (buffer), "%s/%d via %s%s metric %u mss %u",
|
g_snprintf (buffer, sizeof (buffer), "%s/%d via %s%s metric %u mss %u src %s",
|
||||||
s_network, route->plen, s_gateway,
|
s_network, route->plen, s_gateway,
|
||||||
str_dev ? str_dev : "",
|
str_dev ? str_dev : "",
|
||||||
route->metric, route->mss);
|
route->metric, route->mss,
|
||||||
|
source_to_string (route->source));
|
||||||
g_free (str_dev);
|
g_free (str_dev);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
@@ -1843,10 +1885,11 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route)
|
|||||||
s_dev = route->ifindex > 0 ? nm_platform_link_get_name (route->ifindex) : NULL;
|
s_dev = route->ifindex > 0 ? nm_platform_link_get_name (route->ifindex) : NULL;
|
||||||
str_dev = s_dev ? g_strconcat (" dev ", s_dev, NULL) : NULL;
|
str_dev = s_dev ? g_strconcat (" dev ", s_dev, NULL) : NULL;
|
||||||
|
|
||||||
g_snprintf (buffer, sizeof (buffer), "%s/%d via %s%s metric %u mss %u",
|
g_snprintf (buffer, sizeof (buffer), "%s/%d via %s%s metric %u mss %u src %s",
|
||||||
s_network, route->plen, s_gateway,
|
s_network, route->plen, s_gateway,
|
||||||
str_dev ? str_dev : "",
|
str_dev ? str_dev : "",
|
||||||
route->metric, route->mss);
|
route->metric, route->mss,
|
||||||
|
source_to_string (route->source));
|
||||||
g_free (str_dev);
|
g_free (str_dev);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
@@ -1879,9 +1922,10 @@ int
|
|||||||
nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b)
|
nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b)
|
||||||
{
|
{
|
||||||
_CMP_POINTER (a, b);
|
_CMP_POINTER (a, b);
|
||||||
|
_CMP_FIELD (a, b, ifindex);
|
||||||
|
_CMP_FIELD (a, b, source);
|
||||||
_CMP_FIELD_MEMCMP (a, b, address);
|
_CMP_FIELD_MEMCMP (a, b, address);
|
||||||
_CMP_FIELD_MEMCMP (a, b, peer_address);
|
_CMP_FIELD_MEMCMP (a, b, peer_address);
|
||||||
_CMP_FIELD (a, b, ifindex);
|
|
||||||
_CMP_FIELD (a, b, plen);
|
_CMP_FIELD (a, b, plen);
|
||||||
_CMP_FIELD (a, b, timestamp);
|
_CMP_FIELD (a, b, timestamp);
|
||||||
_CMP_FIELD (a, b, lifetime);
|
_CMP_FIELD (a, b, lifetime);
|
||||||
@@ -1894,6 +1938,7 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A
|
|||||||
{
|
{
|
||||||
_CMP_POINTER (a, b);
|
_CMP_POINTER (a, b);
|
||||||
_CMP_FIELD (a, b, ifindex);
|
_CMP_FIELD (a, b, ifindex);
|
||||||
|
_CMP_FIELD (a, b, source);
|
||||||
_CMP_FIELD_MEMCMP (a, b, address);
|
_CMP_FIELD_MEMCMP (a, b, address);
|
||||||
_CMP_FIELD_MEMCMP (a, b, peer_address);
|
_CMP_FIELD_MEMCMP (a, b, peer_address);
|
||||||
_CMP_FIELD (a, b, plen);
|
_CMP_FIELD (a, b, plen);
|
||||||
@@ -1909,6 +1954,7 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route
|
|||||||
{
|
{
|
||||||
_CMP_POINTER (a, b);
|
_CMP_POINTER (a, b);
|
||||||
_CMP_FIELD (a, b, ifindex);
|
_CMP_FIELD (a, b, ifindex);
|
||||||
|
_CMP_FIELD (a, b, source);
|
||||||
_CMP_FIELD_MEMCMP (a, b, network);
|
_CMP_FIELD_MEMCMP (a, b, network);
|
||||||
_CMP_FIELD (a, b, plen);
|
_CMP_FIELD (a, b, plen);
|
||||||
_CMP_FIELD_MEMCMP (a, b, gateway);
|
_CMP_FIELD_MEMCMP (a, b, gateway);
|
||||||
@@ -1922,6 +1968,7 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route
|
|||||||
{
|
{
|
||||||
_CMP_POINTER (a, b);
|
_CMP_POINTER (a, b);
|
||||||
_CMP_FIELD (a, b, ifindex);
|
_CMP_FIELD (a, b, ifindex);
|
||||||
|
_CMP_FIELD (a, b, source);
|
||||||
_CMP_FIELD_MEMCMP (a, b, network);
|
_CMP_FIELD_MEMCMP (a, b, network);
|
||||||
_CMP_FIELD (a, b, plen);
|
_CMP_FIELD (a, b, plen);
|
||||||
_CMP_FIELD_MEMCMP (a, b, gateway);
|
_CMP_FIELD_MEMCMP (a, b, gateway);
|
||||||
|
@@ -119,8 +119,23 @@ typedef struct {
|
|||||||
|
|
||||||
#define NM_PLATFORM_LIFETIME_PERMANENT G_MAXUINT32
|
#define NM_PLATFORM_LIFETIME_PERMANENT G_MAXUINT32
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* In priority order; higher number == higher priority */
|
||||||
|
NM_PLATFORM_SOURCE_UNKNOWN,
|
||||||
|
NM_PLATFORM_SOURCE_KERNEL,
|
||||||
|
NM_PLATFORM_SOURCE_SHARED,
|
||||||
|
NM_PLATFORM_SOURCE_IP4LL,
|
||||||
|
NM_PLATFORM_SOURCE_PPP,
|
||||||
|
NM_PLATFORM_SOURCE_WWAN,
|
||||||
|
NM_PLATFORM_SOURCE_VPN,
|
||||||
|
NM_PLATFORM_SOURCE_DHCP,
|
||||||
|
NM_PLATFORM_SOURCE_RDISC,
|
||||||
|
NM_PLATFORM_SOURCE_USER,
|
||||||
|
} NMPlatformSource;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
NMPlatformSource source;
|
||||||
in_addr_t address;
|
in_addr_t address;
|
||||||
in_addr_t peer_address; /* PTP peer address */
|
in_addr_t peer_address; /* PTP peer address */
|
||||||
int plen;
|
int plen;
|
||||||
@@ -131,6 +146,7 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
NMPlatformSource source;
|
||||||
struct in6_addr address;
|
struct in6_addr address;
|
||||||
struct in6_addr peer_address;
|
struct in6_addr peer_address;
|
||||||
int plen;
|
int plen;
|
||||||
@@ -142,6 +158,7 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
NMPlatformSource source;
|
||||||
in_addr_t network;
|
in_addr_t network;
|
||||||
int plen;
|
int plen;
|
||||||
in_addr_t gateway;
|
in_addr_t gateway;
|
||||||
@@ -151,6 +168,7 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
NMPlatformSource source;
|
||||||
struct in6_addr network;
|
struct in6_addr network;
|
||||||
int plen;
|
int plen;
|
||||||
struct in6_addr gateway;
|
struct in6_addr gateway;
|
||||||
|
@@ -550,6 +550,7 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager,
|
|||||||
address.plen = g_value_get_uint (val);
|
address.plen = g_value_get_uint (val);
|
||||||
|
|
||||||
if (address.address && address.plen) {
|
if (address.address && address.plen) {
|
||||||
|
address.source = NM_PLATFORM_SOURCE_PPP;
|
||||||
nm_ip4_config_add_address (config, &address);
|
nm_ip4_config_add_address (config, &address);
|
||||||
} else {
|
} else {
|
||||||
nm_log_err (LOGD_PPP, "invalid IPv4 address received!");
|
nm_log_err (LOGD_PPP, "invalid IPv4 address received!");
|
||||||
|
@@ -173,6 +173,119 @@ test_subtract (void)
|
|||||||
g_object_unref (dst);
|
g_object_unref (dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_compare_with_source (void)
|
||||||
|
{
|
||||||
|
NMIP4Config *a, *b;
|
||||||
|
NMPlatformIP4Address addr;
|
||||||
|
NMPlatformIP4Route route;
|
||||||
|
|
||||||
|
a = nm_ip4_config_new ();
|
||||||
|
b = nm_ip4_config_new ();
|
||||||
|
|
||||||
|
/* Address */
|
||||||
|
addr_init (&addr, "1.2.3.4", NULL, 24);
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip4_config_add_address (a, &addr);
|
||||||
|
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
nm_ip4_config_add_address (b, &addr);
|
||||||
|
|
||||||
|
/* Route */
|
||||||
|
route_new (&route, "10.0.0.0", 8, "192.168.1.1");
|
||||||
|
route.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip4_config_add_route (a, &route);
|
||||||
|
|
||||||
|
route.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
nm_ip4_config_add_route (b, &route);
|
||||||
|
|
||||||
|
/* Assert that the configs are basically the same, eg that the source is ignored */
|
||||||
|
g_assert (nm_ip4_config_equal (a, b));
|
||||||
|
|
||||||
|
g_object_unref (a);
|
||||||
|
g_object_unref (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_add_address_with_source (void)
|
||||||
|
{
|
||||||
|
NMIP4Config *a;
|
||||||
|
NMPlatformIP4Address addr;
|
||||||
|
const NMPlatformIP4Address *test_addr;
|
||||||
|
|
||||||
|
a = nm_ip4_config_new ();
|
||||||
|
|
||||||
|
/* Test that a higher priority source is not overwritten */
|
||||||
|
addr_init (&addr, "1.2.3.4", NULL, 24);
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip4_config_add_address (a, &addr);
|
||||||
|
|
||||||
|
test_addr = nm_ip4_config_get_address (a, 0);
|
||||||
|
g_assert_cmpint (test_addr->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
nm_ip4_config_add_address (a, &addr);
|
||||||
|
|
||||||
|
test_addr = nm_ip4_config_get_address (a, 0);
|
||||||
|
g_assert_cmpint (test_addr->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
/* Test that a lower priority address source is overwritten */
|
||||||
|
nm_ip4_config_del_address (a, 0);
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_KERNEL;
|
||||||
|
nm_ip4_config_add_address (a, &addr);
|
||||||
|
|
||||||
|
test_addr = nm_ip4_config_get_address (a, 0);
|
||||||
|
g_assert_cmpint (test_addr->source, ==, NM_PLATFORM_SOURCE_KERNEL);
|
||||||
|
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip4_config_add_address (a, &addr);
|
||||||
|
|
||||||
|
test_addr = nm_ip4_config_get_address (a, 0);
|
||||||
|
g_assert_cmpint (test_addr->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
g_object_unref (a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_add_route_with_source (void)
|
||||||
|
{
|
||||||
|
NMIP4Config *a;
|
||||||
|
NMPlatformIP4Route route;
|
||||||
|
const NMPlatformIP4Route *test_route;
|
||||||
|
|
||||||
|
a = nm_ip4_config_new ();
|
||||||
|
|
||||||
|
/* Test that a higher priority source is not overwritten */
|
||||||
|
route_new (&route, "1.2.3.4", 24, "1.2.3.1");
|
||||||
|
route.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip4_config_add_route (a, &route);
|
||||||
|
|
||||||
|
test_route = nm_ip4_config_get_route (a, 0);
|
||||||
|
g_assert_cmpint (test_route->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
route.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
nm_ip4_config_add_route (a, &route);
|
||||||
|
|
||||||
|
test_route = nm_ip4_config_get_route (a, 0);
|
||||||
|
g_assert_cmpint (test_route->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
/* Test that a lower priority address source is overwritten */
|
||||||
|
nm_ip4_config_del_route (a, 0);
|
||||||
|
route.source = NM_PLATFORM_SOURCE_KERNEL;
|
||||||
|
nm_ip4_config_add_route (a, &route);
|
||||||
|
|
||||||
|
test_route = nm_ip4_config_get_route (a, 0);
|
||||||
|
g_assert_cmpint (test_route->source, ==, NM_PLATFORM_SOURCE_KERNEL);
|
||||||
|
|
||||||
|
route.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip4_config_add_route (a, &route);
|
||||||
|
|
||||||
|
test_route = nm_ip4_config_get_route (a, 0);
|
||||||
|
g_assert_cmpint (test_route->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
g_object_unref (a);
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************/
|
/*******************************************/
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -183,6 +296,9 @@ main (int argc, char **argv)
|
|||||||
g_type_init ();
|
g_type_init ();
|
||||||
|
|
||||||
g_test_add_func ("/ip4-config/subtract", test_subtract);
|
g_test_add_func ("/ip4-config/subtract", test_subtract);
|
||||||
|
g_test_add_func ("/ip4-config/compare-with-source", test_compare_with_source);
|
||||||
|
g_test_add_func ("/ip4-config/add-address-with-source", test_add_address_with_source);
|
||||||
|
g_test_add_func ("/ip4-config/add-route-with-source", test_add_route_with_source);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
@@ -160,6 +160,119 @@ test_subtract (void)
|
|||||||
g_object_unref (dst);
|
g_object_unref (dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_compare_with_source (void)
|
||||||
|
{
|
||||||
|
NMIP6Config *a, *b;
|
||||||
|
NMPlatformIP6Address addr;
|
||||||
|
NMPlatformIP6Route route;
|
||||||
|
|
||||||
|
a = nm_ip6_config_new ();
|
||||||
|
b = nm_ip6_config_new ();
|
||||||
|
|
||||||
|
/* Address */
|
||||||
|
addr_init (&addr, "1122:3344:5566::7788", NULL, 64);
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip6_config_add_address (a, &addr);
|
||||||
|
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
nm_ip6_config_add_address (b, &addr);
|
||||||
|
|
||||||
|
/* Route */
|
||||||
|
route_new (&route, "abcd:1234:4321::", 24, "abcd:1234:4321:cdde::2");
|
||||||
|
route.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip6_config_add_route (a, &route);
|
||||||
|
|
||||||
|
route.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
nm_ip6_config_add_route (b, &route);
|
||||||
|
|
||||||
|
/* Assert that the configs are basically the same, eg that the source is ignored */
|
||||||
|
g_assert (nm_ip6_config_equal (a, b));
|
||||||
|
|
||||||
|
g_object_unref (a);
|
||||||
|
g_object_unref (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_add_address_with_source (void)
|
||||||
|
{
|
||||||
|
NMIP6Config *a;
|
||||||
|
NMPlatformIP6Address addr;
|
||||||
|
const NMPlatformIP6Address *test_addr;
|
||||||
|
|
||||||
|
a = nm_ip6_config_new ();
|
||||||
|
|
||||||
|
/* Test that a higher priority source is not overwritten */
|
||||||
|
addr_init (&addr, "1122:3344:5566::7788", NULL, 64);
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip6_config_add_address (a, &addr);
|
||||||
|
|
||||||
|
test_addr = nm_ip6_config_get_address (a, 0);
|
||||||
|
g_assert_cmpint (test_addr->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
nm_ip6_config_add_address (a, &addr);
|
||||||
|
|
||||||
|
test_addr = nm_ip6_config_get_address (a, 0);
|
||||||
|
g_assert_cmpint (test_addr->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
/* Test that a lower priority address source is overwritten */
|
||||||
|
nm_ip6_config_del_address (a, 0);
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_KERNEL;
|
||||||
|
nm_ip6_config_add_address (a, &addr);
|
||||||
|
|
||||||
|
test_addr = nm_ip6_config_get_address (a, 0);
|
||||||
|
g_assert_cmpint (test_addr->source, ==, NM_PLATFORM_SOURCE_KERNEL);
|
||||||
|
|
||||||
|
addr.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip6_config_add_address (a, &addr);
|
||||||
|
|
||||||
|
test_addr = nm_ip6_config_get_address (a, 0);
|
||||||
|
g_assert_cmpint (test_addr->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
g_object_unref (a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_add_route_with_source (void)
|
||||||
|
{
|
||||||
|
NMIP6Config *a;
|
||||||
|
NMPlatformIP6Route route;
|
||||||
|
const NMPlatformIP6Route *test_route;
|
||||||
|
|
||||||
|
a = nm_ip6_config_new ();
|
||||||
|
|
||||||
|
/* Test that a higher priority source is not overwritten */
|
||||||
|
route_new (&route, "abcd:1234:4321::", 24, "abcd:1234:4321:cdde::2");
|
||||||
|
route.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip6_config_add_route (a, &route);
|
||||||
|
|
||||||
|
test_route = nm_ip6_config_get_route (a, 0);
|
||||||
|
g_assert_cmpint (test_route->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
route.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
nm_ip6_config_add_route (a, &route);
|
||||||
|
|
||||||
|
test_route = nm_ip6_config_get_route (a, 0);
|
||||||
|
g_assert_cmpint (test_route->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
/* Test that a lower priority address source is overwritten */
|
||||||
|
nm_ip6_config_del_route (a, 0);
|
||||||
|
route.source = NM_PLATFORM_SOURCE_KERNEL;
|
||||||
|
nm_ip6_config_add_route (a, &route);
|
||||||
|
|
||||||
|
test_route = nm_ip6_config_get_route (a, 0);
|
||||||
|
g_assert_cmpint (test_route->source, ==, NM_PLATFORM_SOURCE_KERNEL);
|
||||||
|
|
||||||
|
route.source = NM_PLATFORM_SOURCE_USER;
|
||||||
|
nm_ip6_config_add_route (a, &route);
|
||||||
|
|
||||||
|
test_route = nm_ip6_config_get_route (a, 0);
|
||||||
|
g_assert_cmpint (test_route->source, ==, NM_PLATFORM_SOURCE_USER);
|
||||||
|
|
||||||
|
g_object_unref (a);
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************/
|
/*******************************************/
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -170,6 +283,9 @@ main (int argc, char **argv)
|
|||||||
g_type_init ();
|
g_type_init ();
|
||||||
|
|
||||||
g_test_add_func ("/ip6-config/subtract", test_subtract);
|
g_test_add_func ("/ip6-config/subtract", test_subtract);
|
||||||
|
g_test_add_func ("/ip6-config/compare-with-source", test_compare_with_source);
|
||||||
|
g_test_add_func ("/ip6-config/add-address-with-source", test_add_address_with_source);
|
||||||
|
g_test_add_func ("/ip6-config/add-route-with-source", test_add_route_with_source);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
@@ -333,6 +333,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
|
|||||||
if (nm_ip4_config_destination_is_direct (parent_config, vpn_gw, 32))
|
if (nm_ip4_config_destination_is_direct (parent_config, vpn_gw, 32))
|
||||||
route.gateway = 0;
|
route.gateway = 0;
|
||||||
|
|
||||||
|
route.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
nm_ip4_config_add_route (config, &route);
|
nm_ip4_config_add_route (config, &route);
|
||||||
|
|
||||||
/* Ensure there's a route to the parent device's gateway through the
|
/* Ensure there's a route to the parent device's gateway through the
|
||||||
@@ -343,6 +344,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
|
|||||||
memset (&route, 0, sizeof (route));
|
memset (&route, 0, sizeof (route));
|
||||||
route.network = parent_gw;
|
route.network = parent_gw;
|
||||||
route.plen = 32;
|
route.plen = 32;
|
||||||
|
route.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
|
||||||
nm_ip4_config_add_route (config, &route);
|
nm_ip4_config_add_route (config, &route);
|
||||||
}
|
}
|
||||||
@@ -378,6 +380,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
|
|||||||
if (nm_ip6_config_destination_is_direct (parent_config, vpn_gw, 128))
|
if (nm_ip6_config_destination_is_direct (parent_config, vpn_gw, 128))
|
||||||
route.gateway = in6addr_any;
|
route.gateway = in6addr_any;
|
||||||
|
|
||||||
|
route.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
nm_ip6_config_add_route (config, &route);
|
nm_ip6_config_add_route (config, &route);
|
||||||
|
|
||||||
/* Ensure there's a route to the parent device's gateway through the
|
/* Ensure there's a route to the parent device's gateway through the
|
||||||
@@ -388,6 +391,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
|
|||||||
memset (&route, 0, sizeof (route));
|
memset (&route, 0, sizeof (route));
|
||||||
route.network = *parent_gw;
|
route.network = *parent_gw;
|
||||||
route.plen = 128;
|
route.plen = 128;
|
||||||
|
route.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
|
||||||
nm_ip6_config_add_route (config, &route);
|
nm_ip6_config_add_route (config, &route);
|
||||||
}
|
}
|
||||||
@@ -944,6 +948,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
|
|||||||
address.plen = g_value_get_uint (val);
|
address.plen = g_value_get_uint (val);
|
||||||
|
|
||||||
if (address.address && address.plen) {
|
if (address.address && address.plen) {
|
||||||
|
address.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
nm_ip4_config_add_address (config, &address);
|
nm_ip4_config_add_address (config, &address);
|
||||||
} else {
|
} else {
|
||||||
nm_log_err (LOGD_VPN, "invalid IP4 config received!");
|
nm_log_err (LOGD_VPN, "invalid IP4 config received!");
|
||||||
@@ -1002,6 +1007,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
|
|||||||
route.network = nm_ip4_route_get_dest (item);
|
route.network = nm_ip4_route_get_dest (item);
|
||||||
route.plen = nm_ip4_route_get_prefix (item);
|
route.plen = nm_ip4_route_get_prefix (item);
|
||||||
route.gateway = nm_ip4_route_get_next_hop (item);
|
route.gateway = nm_ip4_route_get_next_hop (item);
|
||||||
|
route.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
|
||||||
/* Ignore host routes to the VPN gateway since NM adds one itself
|
/* Ignore host routes to the VPN gateway since NM adds one itself
|
||||||
* below. Since NM knows more about the routing situation than
|
* below. Since NM knows more about the routing situation than
|
||||||
@@ -1094,9 +1100,10 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
|
|||||||
if (val)
|
if (val)
|
||||||
address.plen = g_value_get_uint (val);
|
address.plen = g_value_get_uint (val);
|
||||||
|
|
||||||
if (!IN6_IS_ADDR_UNSPECIFIED (&address.address) && address.plen)
|
if (!IN6_IS_ADDR_UNSPECIFIED (&address.address) && address.plen) {
|
||||||
|
address.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
nm_ip6_config_add_address (config, &address);
|
nm_ip6_config_add_address (config, &address);
|
||||||
else {
|
} else {
|
||||||
nm_log_err (LOGD_VPN, "invalid IP6 config received!");
|
nm_log_err (LOGD_VPN, "invalid IP6 config received!");
|
||||||
g_object_unref (config);
|
g_object_unref (config);
|
||||||
nm_vpn_connection_config_maybe_complete (connection, FALSE);
|
nm_vpn_connection_config_maybe_complete (connection, FALSE);
|
||||||
@@ -1145,6 +1152,7 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
|
|||||||
route.network = *nm_ip6_route_get_dest (item);
|
route.network = *nm_ip6_route_get_dest (item);
|
||||||
route.plen = nm_ip6_route_get_prefix (item);
|
route.plen = nm_ip6_route_get_prefix (item);
|
||||||
route.gateway = *nm_ip6_route_get_next_hop (item);
|
route.gateway = *nm_ip6_route_get_next_hop (item);
|
||||||
|
route.source = NM_PLATFORM_SOURCE_VPN;
|
||||||
|
|
||||||
/* Ignore host routes to the VPN gateway since NM adds one itself
|
/* Ignore host routes to the VPN gateway since NM adds one itself
|
||||||
* below. Since NM knows more about the routing situation than
|
* below. Since NM knows more about the routing situation than
|
||||||
|
Reference in New Issue
Block a user