mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-03 15:10:14 +01:00
core: merge branch 'th/platform-route-pt4' (part 2)
Drop NMDefaultRouteManager. https://github.com/NetworkManager/NetworkManager/pull/26
This commit is contained in:
commit
4bc231e33a
18 changed files with 722 additions and 2047 deletions
|
|
@ -1494,8 +1494,6 @@ src_libNetworkManager_la_SOURCES = \
|
|||
src/nm-dcb.h \
|
||||
src/nm-netns.c \
|
||||
src/nm-netns.h \
|
||||
src/nm-default-route-manager.c \
|
||||
src/nm-default-route-manager.h \
|
||||
src/nm-dhcp4-config.c \
|
||||
src/nm-dhcp4-config.h \
|
||||
src/nm-dhcp6-config.c \
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@
|
|||
#include "nm-utils/c-list.h"
|
||||
#include "dns/nm-dns-manager.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-default-route-manager.h"
|
||||
#include "systemd/nm-sd.h"
|
||||
#include "nm-lldp-listener.h"
|
||||
#include "nm-audit-manager.h"
|
||||
|
|
@ -360,14 +359,12 @@ typedef struct _NMDevicePrivate {
|
|||
NMIP4Config * ext_ip4_config; /* Stuff added outside NM */
|
||||
NMIP4Config * wwan_ip4_config; /* WWAN configuration */
|
||||
GSList * vpn4_configs; /* VPNs which use this device */
|
||||
struct {
|
||||
bool v4_has;
|
||||
bool v4_is_assumed;
|
||||
bool v6_has;
|
||||
bool v6_is_assumed;
|
||||
NMPlatformIP4Route v4;
|
||||
NMPlatformIP6Route v6;
|
||||
} default_route;
|
||||
|
||||
const NMPObject *default_route4;
|
||||
const NMPObject *default_route6;
|
||||
const NMPObject *default_routegw4;
|
||||
const NMPObject *default_routegw6;
|
||||
|
||||
bool v4_has_shadowed_routes;
|
||||
const char *ip4_rp_filter;
|
||||
|
||||
|
|
@ -1691,62 +1688,33 @@ out:
|
|||
return nm_utils_ip_route_metric_normalize (addr_family, route_metric);
|
||||
}
|
||||
|
||||
static void
|
||||
_update_default_route (NMDevice *self, int addr_family, gboolean has, gboolean is_assumed)
|
||||
const NMPObject *
|
||||
nm_device_get_best_default_route (NMDevice *self,
|
||||
int addr_family)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
bool *p_has, *p_is_assumed;
|
||||
|
||||
nm_assert (NM_IN_SET (addr_family, 0, AF_INET, AF_INET6));
|
||||
|
||||
if (addr_family == AF_INET) {
|
||||
p_has = &priv->default_route.v4_has;
|
||||
p_is_assumed = &priv->default_route.v4_is_assumed;
|
||||
} else {
|
||||
p_has = &priv->default_route.v6_has;
|
||||
p_is_assumed = &priv->default_route.v6_is_assumed;
|
||||
/* Prefer the best default-route we have in ipx_config.
|
||||
*
|
||||
* Otherwise, use priv->default_routeX. Usually, we would
|
||||
* expect that if ipx_config has no default route, then
|
||||
* also priv->default_routeX is unset. This is just to cover
|
||||
* a case I cannot imagine now. */
|
||||
switch (addr_family) {
|
||||
case AF_INET:
|
||||
return (priv->ip4_config ? nm_ip4_config_best_default_route_get (priv->ip4_config) : NULL)
|
||||
?: priv->default_route4;
|
||||
case AF_INET6:
|
||||
return (priv->ip6_config ? nm_ip6_config_best_default_route_get (priv->ip6_config) : NULL)
|
||||
?: priv->default_route6;
|
||||
case AF_UNSPEC:
|
||||
return (priv->ip4_config ? nm_ip4_config_best_default_route_get (priv->ip4_config) : NULL)
|
||||
?: priv->default_route4
|
||||
?: (priv->ip6_config ? nm_ip6_config_best_default_route_get (priv->ip6_config) : NULL)
|
||||
?: priv->default_route6;
|
||||
default:
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
if (*p_has == has && *p_is_assumed == is_assumed)
|
||||
return;
|
||||
|
||||
*p_has = has;
|
||||
*p_is_assumed = is_assumed;
|
||||
|
||||
if (addr_family == AF_INET)
|
||||
nm_default_route_manager_ip4_update_default_route (nm_netns_get_default_route_manager (priv->netns), self);
|
||||
else
|
||||
nm_default_route_manager_ip6_update_default_route (nm_netns_get_default_route_manager (priv->netns), self);
|
||||
}
|
||||
|
||||
const NMPlatformIP4Route *
|
||||
nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if (out_is_assumed)
|
||||
*out_is_assumed = priv->default_route.v4_is_assumed;
|
||||
|
||||
return priv->default_route.v4_has ? &priv->default_route.v4 : NULL;
|
||||
}
|
||||
|
||||
const NMPlatformIP6Route *
|
||||
nm_device_get_ip6_default_route (NMDevice *self, gboolean *out_is_assumed)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if (out_is_assumed)
|
||||
*out_is_assumed = priv->default_route.v6_is_assumed;
|
||||
|
||||
return priv->default_route.v6_has ? &priv->default_route.v6 : NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
|
|
@ -1863,7 +1831,7 @@ update_connectivity_state (NMDevice *self, NMConnectivityState state)
|
|||
/* If the connectivity check is disabled, make an optimistic guess. */
|
||||
if (state == NM_CONNECTIVITY_UNKNOWN) {
|
||||
if (priv->state == NM_DEVICE_STATE_ACTIVATED) {
|
||||
if (priv->default_route.v4_has || priv->default_route.v6_has)
|
||||
if (nm_device_get_best_default_route (self, AF_UNSPEC))
|
||||
state = NM_CONNECTIVITY_FULL;
|
||||
else
|
||||
state = NM_CONNECTIVITY_LIMITED;
|
||||
|
|
@ -1883,12 +1851,12 @@ update_connectivity_state (NMDevice *self, NMConnectivityState state)
|
|||
|
||||
if ( priv->state == NM_DEVICE_STATE_ACTIVATED
|
||||
&& !nm_device_sys_iface_state_is_external (self)) {
|
||||
if ( priv->default_route.v4_has
|
||||
if ( nm_device_get_best_default_route (self, AF_INET)
|
||||
&& !ip4_config_merge_and_apply (self, NULL, TRUE))
|
||||
_LOGW (LOGD_IP4, "Failed to update IPv4 default route metric");
|
||||
if ( priv->default_route.v6_has
|
||||
_LOGW (LOGD_IP4, "Failed to update IPv4 route metric");
|
||||
if ( nm_device_get_best_default_route (self, AF_INET6)
|
||||
&& !ip6_config_merge_and_apply (self, TRUE))
|
||||
_LOGW (LOGD_IP6, "Failed to update IPv6 default route metric");
|
||||
_LOGW (LOGD_IP6, "Failed to update IPv6 route metric");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2002,7 +1970,7 @@ concheck_periodic_update (NMDevice *self)
|
|||
gboolean check_enable;
|
||||
|
||||
check_enable = (priv->state == NM_DEVICE_STATE_ACTIVATED)
|
||||
&& (priv->default_route.v4_has || priv->default_route.v6_has);
|
||||
&& nm_device_get_best_default_route (self, AF_UNSPEC);
|
||||
|
||||
if (check_enable && !priv->concheck_periodic_id) {
|
||||
/* We just gained a default route. Enable periodic checking. */
|
||||
|
|
@ -2864,7 +2832,7 @@ ip4_rp_filter_update (NMDevice *self)
|
|||
const char *ip4_rp_filter;
|
||||
|
||||
if ( priv->v4_has_shadowed_routes
|
||||
|| priv->default_route.v4_has) {
|
||||
|| nm_device_get_best_default_route (self, AF_INET)) {
|
||||
if (nm_device_ipv4_sysctl_get_uint32 (self, "rp_filter", 0) != 1) {
|
||||
/* Don't touch the rp_filter if it's not strict. */
|
||||
return;
|
||||
|
|
@ -3910,15 +3878,6 @@ nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config)
|
|||
if (!unconfigure_ip_config)
|
||||
return;
|
||||
|
||||
/* Clean up IP configs; this does not actually deconfigure the
|
||||
* interface, it just clears the configuration to which policy
|
||||
* is reacting via NM_DEVICE_IP4_CONFIG_CHANGED/NM_DEVICE_IP6_CONFIG_CHANGED
|
||||
* signal. As NMPolicy registered the NMIPxConfig instances in NMDnsManager,
|
||||
* these would be leaked otherwise. */
|
||||
_update_default_route (self, AF_INET, priv->default_route.v4_has, TRUE);
|
||||
_update_default_route (self, AF_INET6, priv->default_route.v6_has, TRUE);
|
||||
_update_default_route (self, AF_INET, FALSE, TRUE);
|
||||
_update_default_route (self, AF_INET6, FALSE, TRUE);
|
||||
nm_device_set_ip4_config (self, NULL, 0, FALSE);
|
||||
nm_device_set_ip6_config (self, NULL, FALSE);
|
||||
}
|
||||
|
|
@ -5516,49 +5475,6 @@ ipv4ll_start (NMDevice *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
_device_get_default_route_from_platform (NMDevice *self, int addr_family, NMPlatformIPRoute *out_route)
|
||||
{
|
||||
int ifindex = nm_device_get_ip_ifindex (self);
|
||||
const NMDedupMultiHeadEntry *pl_head_entry;
|
||||
NMDedupMultiIter iter;
|
||||
const NMPObject *plobj = NULL;
|
||||
const NMPlatformIPRoute *route = NULL;
|
||||
guint32 route_metric = G_MAXUINT32;
|
||||
|
||||
pl_head_entry = nm_platform_lookup_route_default (nm_device_get_platform (self),
|
||||
addr_family == AF_INET
|
||||
? NMP_OBJECT_TYPE_IP4_ROUTE
|
||||
: NMP_OBJECT_TYPE_IP6_ROUTE);
|
||||
nmp_cache_iter_for_each (&iter, pl_head_entry, &plobj) {
|
||||
guint32 m;
|
||||
const NMPlatformIPRoute *r = NMP_OBJECT_CAST_IP_ROUTE (plobj);
|
||||
|
||||
if ( r->ifindex != ifindex
|
||||
|| r->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL
|
||||
|| r->table_coerced)
|
||||
continue;
|
||||
|
||||
/* if there are several default routes, find the one with the best metric */
|
||||
m = nm_utils_ip_route_metric_normalize (addr_family, r->metric);
|
||||
if (!route || m < route_metric) {
|
||||
route = NMP_OBJECT_CAST_IP_ROUTE (plobj);
|
||||
route_metric = m;
|
||||
}
|
||||
}
|
||||
|
||||
if (route) {
|
||||
if (addr_family == AF_INET)
|
||||
*((NMPlatformIP4Route *) out_route) = *((NMPlatformIP4Route *) route);
|
||||
else
|
||||
*((NMPlatformIP6Route *) out_route) = *((NMPlatformIP6Route *) route);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
ensure_con_ip4_config (NMDevice *self)
|
||||
{
|
||||
|
|
@ -5648,14 +5564,13 @@ ip4_config_merge_and_apply (NMDevice *self,
|
|||
NMConnection *connection;
|
||||
gboolean success;
|
||||
NMIP4Config *composite;
|
||||
gboolean has_direct_route;
|
||||
const guint32 default_route_metric = nm_device_get_ip4_route_metric (self);
|
||||
guint32 gateway;
|
||||
gboolean connection_has_default_route, connection_is_never_default;
|
||||
gboolean ignore_auto_routes = FALSE;
|
||||
gboolean ignore_auto_dns = FALSE;
|
||||
gboolean auto_method = FALSE;
|
||||
GSList *iter;
|
||||
NMPlatformIP4Route default_route;
|
||||
|
||||
/* Merge all the configs into the composite config */
|
||||
if (config) {
|
||||
|
|
@ -5671,10 +5586,6 @@ ip4_config_merge_and_apply (NMDevice *self,
|
|||
if (s_ip4) {
|
||||
ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip4);
|
||||
ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip4);
|
||||
|
||||
if (nm_streq0 (nm_setting_ip_config_get_method (s_ip4),
|
||||
NM_SETTING_IP4_CONFIG_METHOD_AUTO))
|
||||
auto_method = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5718,40 +5629,17 @@ ip4_config_merge_and_apply (NMDevice *self,
|
|||
if (priv->con_ip4_config)
|
||||
nm_ip4_config_merge (composite, priv->con_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
|
||||
/* Add the default route.
|
||||
*
|
||||
* We keep track of the default route of a device in a private field.
|
||||
* NMDevice needs to know the default route at this point, because the gateway
|
||||
* might require a direct route (see below).
|
||||
*
|
||||
* But also, we don't want to add the default route to priv->ip4_config,
|
||||
* because the default route from the setting might not be the same that
|
||||
* NMDefaultRouteManager eventually configures (because the it might
|
||||
* tweak the effective metric).
|
||||
*/
|
||||
|
||||
/* unless we come to a different conclusion below, we have no default route and
|
||||
* the route is assumed. */
|
||||
priv->default_route.v4_has = FALSE;
|
||||
priv->default_route.v4_is_assumed = TRUE;
|
||||
/* Add the default route... */
|
||||
|
||||
if (!commit) {
|
||||
/* during a non-commit event, we always pickup whatever is configured. */
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
}
|
||||
|
||||
/* a generated-assumed connection detects the default route from the platform,
|
||||
* but if the IP method is automatic we need to update the default route to
|
||||
* maintain connectivity.
|
||||
*/
|
||||
if (nm_device_sys_iface_state_is_external (self) && !auto_method)
|
||||
/* for external connections, we always pickup whatever is configured. */
|
||||
if (nm_device_sys_iface_state_is_external (self))
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
||||
/* At this point, we treat assumed and non-assumed connections alike.
|
||||
* For assumed connections we do that because we still manage RA and DHCP
|
||||
* leases for them, so we must extend/update the default route on commits.
|
||||
*/
|
||||
|
||||
connection_has_default_route
|
||||
= nm_utils_connection_has_default_route (connection, AF_INET, &connection_is_never_default);
|
||||
|
||||
|
|
@ -5763,9 +5651,8 @@ ip4_config_merge_and_apply (NMDevice *self,
|
|||
goto END_ADD_DEFAULT_ROUTE;
|
||||
}
|
||||
|
||||
/* we are about to commit (for a non-assumed connection). Enforce whatever we have
|
||||
* configured. */
|
||||
priv->default_route.v4_is_assumed = FALSE;
|
||||
nm_clear_nmp_object (&priv->default_route4);
|
||||
nm_clear_nmp_object (&priv->default_routegw4);
|
||||
|
||||
if (!connection_has_default_route)
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
|
@ -5780,38 +5667,26 @@ ip4_config_merge_and_apply (NMDevice *self,
|
|||
&& nm_device_get_device_type (self) != NM_DEVICE_TYPE_MODEM)
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
||||
has_direct_route = ( gateway == 0
|
||||
|| 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;
|
||||
memset (&priv->default_route.v4, 0, sizeof (priv->default_route.v4));
|
||||
priv->default_route.v4.rt_source = NM_IP_CONFIG_SOURCE_USER;
|
||||
priv->default_route.v4.gateway = gateway;
|
||||
priv->default_route.v4.metric = route_metric_with_penalty (self, default_route_metric);
|
||||
priv->default_route.v4.mss = nm_ip4_config_get_mss (composite);
|
||||
|
||||
if (!has_direct_route) {
|
||||
NMPlatformIP4Route r = priv->default_route.v4;
|
||||
memset (&default_route, 0, sizeof (default_route));
|
||||
default_route.rt_source = NM_IP_CONFIG_SOURCE_USER;
|
||||
default_route.gateway = gateway;
|
||||
default_route.metric = route_metric_with_penalty (self, default_route_metric);
|
||||
default_route.mss = nm_ip4_config_get_mss (composite);
|
||||
nm_clear_nmp_object (&priv->default_route4);
|
||||
nm_ip4_config_add_route (composite, &default_route, &priv->default_route4);
|
||||
|
||||
if (!( gateway == 0
|
||||
|| nm_ip4_config_destination_is_direct (composite, gateway, 32)
|
||||
|| nm_ip4_config_get_direct_route_for_host (composite, gateway))) {
|
||||
/* add a direct route to the gateway */
|
||||
r.network = gateway;
|
||||
r.plen = 32;
|
||||
r.gateway = 0;
|
||||
nm_ip4_config_add_route (composite, &r, NULL);
|
||||
default_route.network = gateway;
|
||||
default_route.plen = 32;
|
||||
default_route.gateway = 0;
|
||||
nm_clear_nmp_object (&priv->default_routegw4);
|
||||
nm_ip4_config_add_route (composite, &default_route, &priv->default_routegw4);
|
||||
}
|
||||
|
||||
END_ADD_DEFAULT_ROUTE:
|
||||
|
||||
if (priv->default_route.v4_is_assumed) {
|
||||
/* If above does not explicitly assign a default route, we always pick up the
|
||||
* default route based on what is currently configured.
|
||||
* That means that even managed connections with never-default, can
|
||||
* get a default route (if configured externally).
|
||||
*/
|
||||
priv->default_route.v4_has = _device_get_default_route_from_platform (self, AF_INET, (NMPlatformIPRoute *) &priv->default_route.v4);
|
||||
}
|
||||
|
||||
if (commit) {
|
||||
if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit)
|
||||
NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, composite);
|
||||
|
|
@ -6369,14 +6244,13 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
NMConnection *connection;
|
||||
gboolean success;
|
||||
NMIP6Config *composite;
|
||||
gboolean has_direct_route;
|
||||
const struct in6_addr *gateway;
|
||||
gboolean connection_has_default_route, connection_is_never_default;
|
||||
gboolean ignore_auto_routes = FALSE;
|
||||
gboolean ignore_auto_dns = FALSE;
|
||||
gboolean auto_method = FALSE;
|
||||
const char *token = NULL;
|
||||
GSList *iter;
|
||||
NMPlatformIP6Route default_route;
|
||||
|
||||
/* Apply ignore-auto-routes and ignore-auto-dns settings */
|
||||
connection = nm_device_get_applied_connection (self);
|
||||
|
|
@ -6391,11 +6265,6 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
|
||||
if (nm_setting_ip6_config_get_addr_gen_mode (ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64)
|
||||
token = nm_setting_ip6_config_get_token (ip6);
|
||||
|
||||
if (NM_IN_STRSET (nm_setting_ip_config_get_method (s_ip6),
|
||||
NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
||||
NM_SETTING_IP6_CONFIG_METHOD_DHCP))
|
||||
auto_method = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6453,40 +6322,17 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
if (priv->con_ip6_config)
|
||||
nm_ip6_config_merge (composite, priv->con_ip6_config, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
|
||||
/* Add the default route.
|
||||
*
|
||||
* We keep track of the default route of a device in a private field.
|
||||
* NMDevice needs to know the default route at this point, because the gateway
|
||||
* might require a direct route (see below).
|
||||
*
|
||||
* But also, we don't want to add the default route to priv->ip6_config,
|
||||
* because the default route from the setting might not be the same that
|
||||
* NMDefaultRouteManager eventually configures (because the it might
|
||||
* tweak the effective metric).
|
||||
*/
|
||||
|
||||
/* unless we come to a different conclusion below, we have no default route and
|
||||
* the route is assumed. */
|
||||
priv->default_route.v6_has = FALSE;
|
||||
priv->default_route.v6_is_assumed = TRUE;
|
||||
/* Add the default route... */
|
||||
|
||||
if (!commit) {
|
||||
/* during a non-commit event, we always pickup whatever is configured. */
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
}
|
||||
|
||||
/* a generated-assumed connection detects the default route from the platform,
|
||||
* but if the IP method is automatic we need to update the default route to
|
||||
* maintain connectivity.
|
||||
*/
|
||||
if (nm_device_sys_iface_state_is_external (self) && !auto_method)
|
||||
/* for external connections, we always pickup whatever is configured. */
|
||||
if (nm_device_sys_iface_state_is_external (self))
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
||||
/* At this point, we treat assumed and non-assumed connections alike.
|
||||
* For assumed connections we do that because we still manage RA and DHCP
|
||||
* leases for them, so we must extend/update the default route on commits.
|
||||
*/
|
||||
|
||||
connection_has_default_route
|
||||
= nm_utils_connection_has_default_route (connection, AF_INET6, &connection_is_never_default);
|
||||
|
||||
|
|
@ -6498,9 +6344,8 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
goto END_ADD_DEFAULT_ROUTE;
|
||||
}
|
||||
|
||||
/* we are about to commit (for a non-assumed connection). Enforce whatever we have
|
||||
* configured. */
|
||||
priv->default_route.v6_is_assumed = FALSE;
|
||||
nm_clear_nmp_object (&priv->default_route6);
|
||||
nm_clear_nmp_object (&priv->default_routegw6);
|
||||
|
||||
if (!connection_has_default_route)
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
|
@ -6514,40 +6359,25 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
if (!gateway)
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
||||
memset (&default_route, 0, sizeof (default_route));
|
||||
default_route.rt_source = NM_IP_CONFIG_SOURCE_USER;
|
||||
default_route.gateway = *gateway;
|
||||
default_route.metric = route_metric_with_penalty (self,
|
||||
nm_device_get_ip6_route_metric (self));
|
||||
default_route.mss = nm_ip6_config_get_mss (composite);
|
||||
nm_clear_nmp_object (&priv->default_route6);
|
||||
nm_ip6_config_add_route (composite, &default_route, &priv->default_route6);
|
||||
|
||||
has_direct_route = nm_ip6_config_get_direct_route_for_host (composite, gateway) != NULL;
|
||||
|
||||
|
||||
|
||||
priv->default_route.v6_has = TRUE;
|
||||
memset (&priv->default_route.v6, 0, sizeof (priv->default_route.v6));
|
||||
priv->default_route.v6.rt_source = NM_IP_CONFIG_SOURCE_USER;
|
||||
priv->default_route.v6.gateway = *gateway;
|
||||
priv->default_route.v6.metric = route_metric_with_penalty (self,
|
||||
nm_device_get_ip6_route_metric (self));
|
||||
priv->default_route.v6.mss = nm_ip6_config_get_mss (composite);
|
||||
|
||||
if (!has_direct_route) {
|
||||
NMPlatformIP6Route r = priv->default_route.v6;
|
||||
|
||||
if (!nm_ip6_config_get_direct_route_for_host (composite, gateway)) {
|
||||
/* add a direct route to the gateway */
|
||||
r.network = *gateway;
|
||||
r.plen = 128;
|
||||
r.gateway = in6addr_any;
|
||||
nm_ip6_config_add_route (composite, &r, NULL);
|
||||
default_route.network = *gateway;
|
||||
default_route.plen = 128;
|
||||
default_route.gateway = in6addr_any;
|
||||
nm_clear_nmp_object (&priv->default_routegw6);
|
||||
nm_ip6_config_add_route (composite, &default_route, &priv->default_routegw6);
|
||||
}
|
||||
|
||||
END_ADD_DEFAULT_ROUTE:
|
||||
|
||||
if (priv->default_route.v6_is_assumed) {
|
||||
/* If above does not explicitly assign a default route, we always pick up the
|
||||
* default route based on what is currently configured.
|
||||
* That means that even managed connections with never-default, can
|
||||
* get a default route (if configured externally).
|
||||
*/
|
||||
priv->default_route.v6_has = _device_get_default_route_from_platform (self, AF_INET6, (NMPlatformIPRoute *) &priv->default_route.v6);
|
||||
}
|
||||
|
||||
/* Allow setting MTU etc */
|
||||
if (commit) {
|
||||
NMUtilsIPv6IfaceId iid;
|
||||
|
|
@ -8914,6 +8744,8 @@ _cleanup_ip4_pre (NMDevice *self, CleanupType cleanup_type)
|
|||
_LOGD (LOGD_DEVICE, "clearing queued IP4 config change");
|
||||
priv->queued_ip4_config_pending = FALSE;
|
||||
|
||||
nm_clear_nmp_object (&priv->default_route4);
|
||||
nm_clear_nmp_object (&priv->default_routegw4);
|
||||
dhcp4_cleanup (self, cleanup_type, FALSE);
|
||||
arp_cleanup (self);
|
||||
dnsmasq_cleanup (self);
|
||||
|
|
@ -8931,6 +8763,8 @@ _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type)
|
|||
_LOGD (LOGD_DEVICE, "clearing queued IP6 config change");
|
||||
priv->queued_ip6_config_pending = FALSE;
|
||||
|
||||
nm_clear_nmp_object (&priv->default_route6);
|
||||
nm_clear_nmp_object (&priv->default_routegw6);
|
||||
g_clear_object (&priv->dad6_ip6_config);
|
||||
dhcp6_cleanup (self, cleanup_type, FALSE);
|
||||
linklocal6_cleanup (self);
|
||||
|
|
@ -9887,7 +9721,6 @@ nm_device_set_ip4_config (NMDevice *self,
|
|||
NMIP4Config *old_config = NULL;
|
||||
gboolean has_changes = FALSE;
|
||||
gboolean success = TRUE;
|
||||
gboolean def_route_changed;
|
||||
int ip_ifindex = 0;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
||||
|
|
@ -9940,7 +9773,6 @@ nm_device_set_ip4_config (NMDevice *self,
|
|||
g_clear_object (&priv->dev_ip4_config);
|
||||
}
|
||||
|
||||
def_route_changed = nm_default_route_manager_ip4_update_default_route (nm_netns_get_default_route_manager (priv->netns), self);
|
||||
concheck_periodic_update (self);
|
||||
|
||||
if (!nm_device_sys_iface_state_is_external_or_assume (self))
|
||||
|
|
@ -9974,9 +9806,6 @@ nm_device_set_ip4_config (NMDevice *self,
|
|||
}
|
||||
|
||||
nm_device_queue_recheck_assume (self);
|
||||
} else if (def_route_changed) {
|
||||
_LOGD (LOGD_IP4, "ip4-config: default route changed");
|
||||
g_signal_emit (self, signals[IP4_CONFIG_CHANGED], 0, priv->ip4_config, priv->ip4_config);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
|
@ -10059,7 +9888,6 @@ nm_device_set_ip6_config (NMDevice *self,
|
|||
NMIP6Config *old_config = NULL;
|
||||
gboolean has_changes = FALSE;
|
||||
gboolean success = TRUE;
|
||||
gboolean def_route_changed;
|
||||
int ip_ifindex = 0;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
||||
|
|
@ -10110,8 +9938,6 @@ nm_device_set_ip6_config (NMDevice *self,
|
|||
nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
|
||||
}
|
||||
|
||||
def_route_changed = nm_default_route_manager_ip6_update_default_route (nm_netns_get_default_route_manager (priv->netns), self);
|
||||
|
||||
if (has_changes) {
|
||||
NMSettingsConnection *settings_connection;
|
||||
|
||||
|
|
@ -10141,9 +9967,6 @@ nm_device_set_ip6_config (NMDevice *self,
|
|||
|
||||
if (priv->ndisc)
|
||||
ndisc_set_router_config (priv->ndisc, self);
|
||||
} else if (def_route_changed) {
|
||||
_LOGD (LOGD_IP6, "ip6-config: default route changed");
|
||||
g_signal_emit (self, signals[IP6_CONFIG_CHANGED], 0, priv->ip6_config, priv->ip6_config);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
|
@ -10798,6 +10621,12 @@ update_ip4_config (NMDevice *self, gboolean initial)
|
|||
nm_ip4_config_intersect (priv->wwan_ip4_config, priv->ext_ip4_config);
|
||||
for (iter = priv->vpn4_configs; iter; iter = iter->next)
|
||||
nm_ip4_config_intersect (iter->data, priv->ext_ip4_config);
|
||||
if ( priv->default_route4
|
||||
&& !nm_ip4_config_nmpobj_lookup (priv->ext_ip4_config, priv->default_route4))
|
||||
nm_clear_nmp_object (&priv->default_route4);
|
||||
if ( priv->default_routegw4
|
||||
&& !nm_ip4_config_nmpobj_lookup (priv->ext_ip4_config, priv->default_routegw4))
|
||||
nm_clear_nmp_object (&priv->default_routegw4);
|
||||
|
||||
/* Remove parts from ext_ip4_config to only contain the information that
|
||||
* was configured externally -- we already have the same configuration from
|
||||
|
|
@ -10810,6 +10639,10 @@ update_ip4_config (NMDevice *self, gboolean initial)
|
|||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->wwan_ip4_config);
|
||||
for (iter = priv->vpn4_configs; iter; iter = iter->next)
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, iter->data);
|
||||
if (priv->default_route4)
|
||||
nm_ip4_config_nmpobj_remove (priv->ext_ip4_config, priv->default_route4);
|
||||
if (priv->default_routegw4)
|
||||
nm_ip4_config_nmpobj_remove (priv->ext_ip4_config, priv->default_routegw4);
|
||||
|
||||
ip4_config_merge_and_apply (self, NULL, FALSE);
|
||||
}
|
||||
|
|
@ -10870,6 +10703,12 @@ update_ip6_config (NMDevice *self, gboolean initial)
|
|||
nm_ip6_config_intersect (priv->wwan_ip6_config, priv->ext_ip6_config);
|
||||
for (iter = priv->vpn6_configs; iter; iter = iter->next)
|
||||
nm_ip6_config_intersect (iter->data, priv->ext_ip6_config);
|
||||
if ( priv->default_route6
|
||||
&& !nm_ip6_config_nmpobj_lookup (priv->ext_ip6_config, priv->default_route6))
|
||||
nm_clear_nmp_object (&priv->default_route6);
|
||||
if ( priv->default_routegw6
|
||||
&& !nm_ip6_config_nmpobj_lookup (priv->ext_ip6_config, priv->default_routegw6))
|
||||
nm_clear_nmp_object (&priv->default_routegw6);
|
||||
|
||||
/* Remove parts from ext_ip6_config to only contain the information that
|
||||
* was configured externally -- we already have the same configuration from
|
||||
|
|
@ -10884,6 +10723,10 @@ update_ip6_config (NMDevice *self, gboolean initial)
|
|||
nm_ip6_config_subtract (priv->ext_ip6_config, priv->wwan_ip6_config);
|
||||
for (iter = priv->vpn6_configs; iter; iter = iter->next)
|
||||
nm_ip6_config_subtract (priv->ext_ip6_config, iter->data);
|
||||
if (priv->default_route6)
|
||||
nm_ip6_config_nmpobj_remove (priv->ext_ip6_config, priv->default_route6);
|
||||
if (priv->default_routegw6)
|
||||
nm_ip6_config_nmpobj_remove (priv->ext_ip6_config, priv->default_routegw6);
|
||||
|
||||
ip6_config_merge_and_apply (self, FALSE);
|
||||
}
|
||||
|
|
@ -12118,16 +11961,6 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type)
|
|||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) {
|
||||
_update_default_route (self, AF_INET, FALSE, FALSE);
|
||||
_update_default_route (self, AF_INET6, FALSE, FALSE);
|
||||
} else {
|
||||
_update_default_route (self, AF_INET, priv->default_route.v4_has, TRUE);
|
||||
_update_default_route (self, AF_INET6, priv->default_route.v6_has, TRUE);
|
||||
}
|
||||
_update_default_route (self, AF_INET, FALSE, TRUE);
|
||||
_update_default_route (self, AF_INET6, FALSE, TRUE);
|
||||
|
||||
priv->v4_commit_first_time = TRUE;
|
||||
priv->v6_commit_first_time = TRUE;
|
||||
|
||||
|
|
@ -12138,6 +11971,10 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type)
|
|||
*/
|
||||
nm_device_set_ip4_config (self, NULL, 0, TRUE);
|
||||
nm_device_set_ip6_config (self, NULL, TRUE);
|
||||
nm_clear_nmp_object (&priv->default_route4);
|
||||
nm_clear_nmp_object (&priv->default_route6);
|
||||
nm_clear_nmp_object (&priv->default_routegw4);
|
||||
nm_clear_nmp_object (&priv->default_routegw6);
|
||||
g_clear_object (&priv->proxy_config);
|
||||
g_clear_object (&priv->con_ip4_config);
|
||||
g_clear_object (&priv->dev_ip4_config);
|
||||
|
|
@ -13819,9 +13656,6 @@ nm_device_init (NMDevice *self)
|
|||
priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
|
||||
priv->sys_iface_state = NM_DEVICE_SYS_IFACE_STATE_EXTERNAL;
|
||||
|
||||
priv->default_route.v4_is_assumed = TRUE;
|
||||
priv->default_route.v6_is_assumed = TRUE;
|
||||
|
||||
priv->v4_commit_first_time = TRUE;
|
||||
priv->v6_commit_first_time = TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -710,8 +710,8 @@ gboolean nm_device_owns_iface (NMDevice *device, const char *iface);
|
|||
|
||||
NMConnection *nm_device_new_default_connection (NMDevice *self);
|
||||
|
||||
const NMPlatformIP4Route *nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed);
|
||||
const NMPlatformIP6Route *nm_device_get_ip6_default_route (NMDevice *self, gboolean *out_is_assumed);
|
||||
const NMPObject *nm_device_get_best_default_route (NMDevice *self,
|
||||
int addr_family);
|
||||
|
||||
void nm_device_spawn_iface_helper (NMDevice *self);
|
||||
|
||||
|
|
|
|||
|
|
@ -91,8 +91,10 @@ get_ip4_rdns_domains (NMIP4Config *ip4)
|
|||
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &address)
|
||||
nm_utils_get_reverse_dns_domains_ip4 (address->address, address->plen, domains);
|
||||
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route)
|
||||
nm_utils_get_reverse_dns_domains_ip4 (route->network, route->plen, domains);
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) {
|
||||
if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
nm_utils_get_reverse_dns_domains_ip4 (route->network, route->plen, domains);
|
||||
}
|
||||
|
||||
/* Terminating NULL so we can use g_strfreev() to free it */
|
||||
g_ptr_array_add (domains, NULL);
|
||||
|
|
@ -119,8 +121,10 @@ get_ip6_rdns_domains (NMIP6Config *ip6)
|
|||
nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &address)
|
||||
nm_utils_get_reverse_dns_domains_ip6 (&address->address, address->plen, domains);
|
||||
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route)
|
||||
nm_utils_get_reverse_dns_domains_ip6 (&route->network, route->plen, domains);
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route) {
|
||||
if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
nm_utils_get_reverse_dns_domains_ip6 (&route->network, route->plen, domains);
|
||||
}
|
||||
|
||||
/* Terminating NULL so we can use g_strfreev() to free it */
|
||||
g_ptr_array_add (domains, NULL);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,64 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NETWORKMANAGER_DEFAULT_ROUTE_MANAGER_H__
|
||||
#define __NETWORKMANAGER_DEFAULT_ROUTE_MANAGER_H__
|
||||
|
||||
#include "nm-connection.h"
|
||||
|
||||
#define NM_TYPE_DEFAULT_ROUTE_MANAGER (nm_default_route_manager_get_type ())
|
||||
#define NM_DEFAULT_ROUTE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEFAULT_ROUTE_MANAGER, NMDefaultRouteManager))
|
||||
#define NM_DEFAULT_ROUTE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEFAULT_ROUTE_MANAGER, NMDefaultRouteManagerClass))
|
||||
#define NM_IS_DEFAULT_ROUTE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEFAULT_ROUTE_MANAGER))
|
||||
#define NM_IS_DEFAULT_ROUTE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEFAULT_ROUTE_MANAGER))
|
||||
#define NM_DEFAULT_ROUTE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEFAULT_ROUTE_MANAGER, NMDefaultRouteManagerClass))
|
||||
|
||||
#define NM_DEFAULT_ROUTE_MANAGER_LOG_WITH_PTR "log-with-ptr"
|
||||
#define NM_DEFAULT_ROUTE_MANAGER_PLATFORM "platform"
|
||||
|
||||
typedef struct _NMDefaultRouteManagerClass NMDefaultRouteManagerClass;
|
||||
|
||||
GType nm_default_route_manager_get_type (void);
|
||||
|
||||
NMDefaultRouteManager *nm_default_route_manager_new (gboolean log_with_ptr, NMPlatform *platform);
|
||||
|
||||
gboolean nm_default_route_manager_ip4_update_default_route (NMDefaultRouteManager *manager, gpointer source);
|
||||
gboolean nm_default_route_manager_ip6_update_default_route (NMDefaultRouteManager *manager, gpointer source);
|
||||
|
||||
NMDevice *nm_default_route_manager_ip4_get_best_device (NMDefaultRouteManager *manager, const GSList *devices, gboolean fully_activated, NMDevice *preferred_device);
|
||||
NMDevice *nm_default_route_manager_ip6_get_best_device (NMDefaultRouteManager *manager, const GSList *devices, gboolean fully_activated, NMDevice *preferred_device);
|
||||
|
||||
NMIP4Config *nm_default_route_manager_ip4_get_best_config (NMDefaultRouteManager *manager,
|
||||
gboolean ignore_never_default,
|
||||
const char **out_ip_iface,
|
||||
NMActiveConnection **out_ac,
|
||||
NMDevice **out_device,
|
||||
NMVpnConnection **out_vpn);
|
||||
NMIP6Config *nm_default_route_manager_ip6_get_best_config (NMDefaultRouteManager *manager,
|
||||
gboolean ignore_never_default,
|
||||
const char **out_ip_iface,
|
||||
NMActiveConnection **out_ac,
|
||||
NMDevice **out_device,
|
||||
NMVpnConnection **out_vpn);
|
||||
|
||||
gboolean nm_default_route_manager_resync (NMDefaultRouteManager *self,
|
||||
int af_family);
|
||||
|
||||
#endif /* NM_DEFAULT_ROUTE_MANAGER_H */
|
||||
|
|
@ -166,6 +166,8 @@ dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder)
|
|||
/* Static routes */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau"));
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) {
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
continue;
|
||||
array[0] = route->network;
|
||||
array[1] = route->plen;
|
||||
array[2] = route->gateway;
|
||||
|
|
@ -235,6 +237,8 @@ dump_ip6_to_props (NMIP6Config *ip6, GVariantBuilder *builder)
|
|||
/* Static routes */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("a(ayuayu)"));
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route) {
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
continue;
|
||||
ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
&route->network,
|
||||
sizeof (struct in6_addr), 1);
|
||||
|
|
|
|||
|
|
@ -377,6 +377,7 @@ typedef struct {
|
|||
GVariant *route_data_variant;
|
||||
GVariant *routes_variant;
|
||||
NMDedupMultiIndex *multi_idx;
|
||||
const NMPObject *best_default_route;
|
||||
union {
|
||||
NMIPConfigDedupMultiIdxType idx_ip4_addresses_;
|
||||
NMDedupMultiIdxType idx_ip4_addresses;
|
||||
|
|
@ -471,6 +472,95 @@ 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
|
||||
|| ( !obj_cur
|
||||
&& NM_IN_SET (NMP_OBJECT_GET_TYPE (obj_cmp), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE))
|
||||
|| NMP_OBJECT_GET_TYPE (obj_cur) == NMP_OBJECT_GET_TYPE (obj_cmp));
|
||||
nm_assert ( !obj_cur
|
||||
|| nm_ip_config_best_default_route_is (obj_cur));
|
||||
|
||||
/* assumes that @obj_cur is already the best default route (or NULL). It checks whether
|
||||
* @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)) {
|
||||
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);
|
||||
|
||||
if (metric_cmp < metric_cur)
|
||||
return obj_cmp;
|
||||
|
||||
if (metric_cmp == metric_cur) {
|
||||
/* 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
|
||||
* (and merged). */
|
||||
c = nmp_object_cmp (obj_cur, obj_cmp);
|
||||
if (c != 0)
|
||||
return c < 0 ? obj_cur : obj_cmp;
|
||||
|
||||
/* as last resort, compare pointers. */
|
||||
if (obj_cmp < obj_cur)
|
||||
return obj_cmp;
|
||||
}
|
||||
}
|
||||
return obj_cur;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_ip_config_best_default_route_set (const NMPObject **best_default_route, const NMPObject *new_candidate)
|
||||
{
|
||||
if (new_candidate == *best_default_route)
|
||||
return FALSE;
|
||||
nmp_object_ref (new_candidate);
|
||||
nm_clear_nmp_object (best_default_route);
|
||||
*best_default_route = new_candidate;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_ip_config_best_default_route_merge (const NMPObject **best_default_route, const NMPObject *new_candidate)
|
||||
{
|
||||
new_candidate = _nm_ip_config_best_default_route_find_better (*best_default_route,
|
||||
new_candidate);
|
||||
return _nm_ip_config_best_default_route_set (best_default_route, new_candidate);
|
||||
}
|
||||
|
||||
const NMPObject *
|
||||
nm_ip4_config_best_default_route_get (const NMIP4Config *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_IP4_CONFIG (self), NULL);
|
||||
|
||||
return NM_IP4_CONFIG_GET_PRIVATE (self)->best_default_route;
|
||||
}
|
||||
|
||||
const NMPObject *
|
||||
_nm_ip4_config_best_default_route_find (const NMIP4Config *self)
|
||||
{
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPObject *new_best_default_route = NULL;
|
||||
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, NULL) {
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route,
|
||||
ipconf_iter.current->obj);
|
||||
}
|
||||
return new_best_default_route;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_notify_addresses (NMIP4Config *self)
|
||||
{
|
||||
|
|
@ -487,6 +577,7 @@ _notify_routes (NMIP4Config *self)
|
|||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (priv->best_default_route == _nm_ip4_config_best_default_route_find (self));
|
||||
nm_clear_g_variant (&priv->route_data_variant);
|
||||
nm_clear_g_variant (&priv->routes_variant);
|
||||
_notify (self, PROP_ROUTE_DATA);
|
||||
|
|
@ -688,8 +779,6 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
continue;
|
||||
if (route->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL)
|
||||
continue;
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
continue;
|
||||
_add_route (self, plobj, NULL, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1056,8 +1145,7 @@ nm_ip4_config_create_setting (const NMIP4Config *self)
|
|||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, &route) {
|
||||
NMIPRoute *s_route;
|
||||
|
||||
/* Ignore default route. */
|
||||
if (!route->plen)
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
continue;
|
||||
|
||||
/* Ignore routes provided by external sources */
|
||||
|
|
@ -1133,10 +1221,8 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl
|
|||
|
||||
/* routes */
|
||||
if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
|
||||
const NMPlatformIP4Route *route;
|
||||
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &route)
|
||||
_add_route (dst, NMP_OBJECT_UP_CAST (route), NULL, NULL);
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, NULL)
|
||||
_add_route (dst, ipconf_iter.current->obj, NULL, NULL);
|
||||
}
|
||||
|
||||
if (dst_priv->route_metric == -1)
|
||||
|
|
@ -1310,6 +1396,7 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
|
|||
const NMPlatformIP4Route *r;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
gboolean changed;
|
||||
gboolean changed_default_route;
|
||||
|
||||
g_return_if_fail (src != NULL);
|
||||
g_return_if_fail (dst != NULL);
|
||||
|
|
@ -1349,12 +1436,24 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
|
|||
|
||||
/* routes */
|
||||
changed = FALSE;
|
||||
changed_default_route = FALSE;
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &r) {
|
||||
nm_auto_nmpobj const NMPObject *obj_old = NULL;
|
||||
|
||||
if (nm_dedup_multi_index_remove_obj (dst_priv->multi_idx,
|
||||
&dst_priv->idx_ip4_routes,
|
||||
NMP_OBJECT_UP_CAST (r),
|
||||
NULL))
|
||||
(gconstpointer *) &obj_old)) {
|
||||
if (dst_priv->best_default_route == obj_old) {
|
||||
nm_clear_nmp_object (&dst_priv->best_default_route);
|
||||
changed_default_route = TRUE;
|
||||
}
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
if (changed_default_route) {
|
||||
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route,
|
||||
_nm_ip4_config_best_default_route_find (dst));
|
||||
}
|
||||
if (changed)
|
||||
_notify_routes (dst);
|
||||
|
|
@ -1421,16 +1520,17 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src)
|
|||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP4Address *a;
|
||||
const NMPlatformIP4Route *r;
|
||||
const NMPObject *new_best_default_route;
|
||||
gboolean changed;
|
||||
|
||||
g_return_if_fail (src);
|
||||
g_return_if_fail (dst);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (dst));
|
||||
|
||||
dst_priv = NM_IP4_CONFIG_GET_PRIVATE (dst);
|
||||
src_priv = NM_IP4_CONFIG_GET_PRIVATE (src);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (dst));
|
||||
|
||||
/* addresses */
|
||||
changed = FALSE;
|
||||
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, dst, &a) {
|
||||
|
|
@ -1459,17 +1559,24 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src)
|
|||
|
||||
/* routes */
|
||||
changed = FALSE;
|
||||
new_best_default_route = NULL;
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, dst, &r) {
|
||||
const NMPObject *o = NMP_OBJECT_UP_CAST (r);
|
||||
|
||||
if (nm_dedup_multi_index_lookup_obj (src_priv->multi_idx,
|
||||
&src_priv->idx_ip4_routes,
|
||||
NMP_OBJECT_UP_CAST (r)))
|
||||
o)) {
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, o);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nm_dedup_multi_index_remove_entry (dst_priv->multi_idx,
|
||||
ipconf_iter.current) != 1)
|
||||
nm_assert_not_reached ();
|
||||
changed = TRUE;
|
||||
}
|
||||
if (_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route))
|
||||
nm_assert (changed);
|
||||
if (changed)
|
||||
_notify_routes (dst);
|
||||
|
||||
|
|
@ -1509,6 +1616,7 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
|
|||
const NMIP4ConfigPrivate *src_priv;
|
||||
NMDedupMultiIter ipconf_iter_src, ipconf_iter_dst;
|
||||
const NMDedupMultiHeadEntry *head_entry_src;
|
||||
const NMPObject *new_best_default_route;
|
||||
|
||||
g_return_val_if_fail (src != NULL, FALSE);
|
||||
g_return_val_if_fail (dst != NULL, FALSE);
|
||||
|
|
@ -1627,19 +1735,25 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
|
|||
}
|
||||
if (!are_equal) {
|
||||
has_minor_changes = TRUE;
|
||||
new_best_default_route = NULL;
|
||||
nm_dedup_multi_index_dirty_set_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes);
|
||||
nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) {
|
||||
const NMPObject *o = ipconf_iter_src.current->obj;
|
||||
const NMPObject *obj_new;
|
||||
|
||||
_nm_ip_config_add_obj (dst_priv->multi_idx,
|
||||
&dst_priv->idx_ip4_routes_,
|
||||
dst_priv->ifindex,
|
||||
ipconf_iter_src.current->obj,
|
||||
o,
|
||||
NULL,
|
||||
FALSE,
|
||||
TRUE,
|
||||
NULL,
|
||||
NULL);
|
||||
&obj_new);
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
|
||||
}
|
||||
nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes, FALSE);
|
||||
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route);
|
||||
_notify_routes (dst);
|
||||
}
|
||||
|
||||
|
|
@ -2028,18 +2142,12 @@ nm_ip4_config_add_address (NMIP4Config *self, const NMPlatformIP4Address *new)
|
|||
void
|
||||
_nmtst_ip4_config_del_address (NMIP4Config *self, guint i)
|
||||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
const NMPlatformIP4Address *a;
|
||||
|
||||
a = _nmtst_ip4_config_get_address (self, i);
|
||||
g_return_if_fail (a);
|
||||
|
||||
if (nm_dedup_multi_index_remove_obj (priv->multi_idx,
|
||||
&priv->idx_ip4_addresses,
|
||||
NMP_OBJECT_UP_CAST (a),
|
||||
NULL) != 1)
|
||||
g_return_if_reached ();
|
||||
_notify_addresses (self);
|
||||
if (!nm_ip4_config_nmpobj_remove (self,
|
||||
NMP_OBJECT_UP_CAST (a)))
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
guint
|
||||
|
|
@ -2121,8 +2229,10 @@ nm_ip4_config_reset_routes (NMIP4Config *self)
|
|||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
if (nm_dedup_multi_index_remove_idx (priv->multi_idx,
|
||||
&priv->idx_ip4_routes) > 0)
|
||||
&priv->idx_ip4_routes) > 0) {
|
||||
nm_clear_nmp_object (&priv->best_default_route);
|
||||
_notify_routes (self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2132,6 +2242,7 @@ _add_route (NMIP4Config *self,
|
|||
const NMPObject **out_obj_new)
|
||||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
nm_auto_nmpobj const NMPObject *obj_old = NULL;
|
||||
const NMPObject *obj_new_2;
|
||||
|
||||
nm_assert ((!new) != (!obj_new));
|
||||
|
|
@ -2145,8 +2256,12 @@ _add_route (NMIP4Config *self,
|
|||
(const NMPlatformObject *) new,
|
||||
TRUE,
|
||||
FALSE,
|
||||
NULL,
|
||||
&obj_old,
|
||||
&obj_new_2)) {
|
||||
if ( priv->best_default_route == obj_old
|
||||
&& obj_old != obj_new_2)
|
||||
nm_clear_nmp_object (&priv->best_default_route);
|
||||
_nm_ip_config_best_default_route_merge (&priv->best_default_route, obj_new_2);
|
||||
NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2));
|
||||
_notify_routes (self);
|
||||
} else
|
||||
|
|
@ -2172,7 +2287,7 @@ nm_ip4_config_add_route (NMIP4Config *self,
|
|||
{
|
||||
g_return_if_fail (self);
|
||||
g_return_if_fail (new);
|
||||
g_return_if_fail (new->plen > 0 && new->plen <= 32);
|
||||
g_return_if_fail (new->plen <= 32);
|
||||
g_return_if_fail (NM_IP4_CONFIG_GET_PRIVATE (self)->ifindex > 0);
|
||||
|
||||
_add_route (self, NULL, new, out_obj_new);
|
||||
|
|
@ -2181,18 +2296,12 @@ nm_ip4_config_add_route (NMIP4Config *self,
|
|||
void
|
||||
_nmtst_ip4_config_del_route (NMIP4Config *self, guint i)
|
||||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
const NMPlatformIP4Route *r;
|
||||
|
||||
r = _nmtst_ip4_config_get_route (self, i);
|
||||
g_return_if_fail (r);
|
||||
|
||||
if (nm_dedup_multi_index_remove_obj (priv->multi_idx,
|
||||
&priv->idx_ip4_routes,
|
||||
NMP_OBJECT_UP_CAST (r),
|
||||
NULL) != 1)
|
||||
g_return_if_reached ();
|
||||
_notify_routes (self);
|
||||
if (!nm_ip4_config_nmpobj_remove (self,
|
||||
NMP_OBJECT_UP_CAST (r)))
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
guint
|
||||
|
|
@ -2701,6 +2810,84 @@ nm_ip4_config_get_metered (const NMIP4Config *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
const NMPObject *
|
||||
nm_ip4_config_nmpobj_lookup (const NMIP4Config *self, const NMPObject *needle)
|
||||
{
|
||||
const NMIP4ConfigPrivate *priv;
|
||||
const NMDedupMultiIdxType *idx_type;
|
||||
|
||||
g_return_val_if_fail (NM_IS_IP4_CONFIG (self), NULL);
|
||||
|
||||
priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
switch (NMP_OBJECT_GET_TYPE (needle)) {
|
||||
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
||||
idx_type = &priv->idx_ip4_addresses;
|
||||
break;
|
||||
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
||||
idx_type = &priv->idx_ip4_routes;
|
||||
break;
|
||||
default:
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
return nm_dedup_multi_entry_get_obj (nm_dedup_multi_index_lookup_obj (priv->multi_idx,
|
||||
idx_type,
|
||||
needle));
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_ip4_config_nmpobj_remove (NMIP4Config *self,
|
||||
const NMPObject *needle)
|
||||
{
|
||||
NMIP4ConfigPrivate *priv;
|
||||
NMDedupMultiIdxType *idx_type;
|
||||
nm_auto_nmpobj const NMPObject *obj_old = NULL;
|
||||
guint n;
|
||||
|
||||
g_return_val_if_fail (NM_IS_IP4_CONFIG (self), FALSE);
|
||||
|
||||
priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
switch (NMP_OBJECT_GET_TYPE (needle)) {
|
||||
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
||||
idx_type = &priv->idx_ip4_addresses;
|
||||
break;
|
||||
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
||||
idx_type = &priv->idx_ip4_routes;
|
||||
break;
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
n = nm_dedup_multi_index_remove_obj (priv->multi_idx,
|
||||
idx_type,
|
||||
needle,
|
||||
(gconstpointer *) &obj_old);
|
||||
if (n != 1) {
|
||||
nm_assert (n == 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nm_assert (NMP_OBJECT_GET_TYPE (obj_old) == NMP_OBJECT_GET_TYPE (needle));
|
||||
|
||||
switch (NMP_OBJECT_GET_TYPE (obj_old)) {
|
||||
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
||||
_notify_addresses (self);
|
||||
break;
|
||||
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
||||
if (priv->best_default_route == obj_old) {
|
||||
_nm_ip_config_best_default_route_set (&priv->best_default_route,
|
||||
_nm_ip4_config_best_default_route_find (self));
|
||||
}
|
||||
_notify_routes (self);
|
||||
break;
|
||||
default:
|
||||
nm_assert_not_reached ();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline void
|
||||
hash_u32 (GChecksum *sum, guint32 n)
|
||||
{
|
||||
|
|
@ -3056,6 +3243,8 @@ finalize (GObject *object)
|
|||
NMIP4Config *self = NM_IP4_CONFIG (object);
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
nm_clear_nmp_object (&priv->best_default_route);
|
||||
|
||||
nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip4_addresses);
|
||||
nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip4_routes);
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,25 @@ nm_ip_config_iter_ip4_route_next (NMDedupMultiIter *ipconf_iter, const NMPlatfor
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline gboolean
|
||||
nm_ip_config_best_default_route_is (const NMPObject *obj)
|
||||
{
|
||||
const NMPlatformIPRoute *r = NMP_OBJECT_CAST_IP_ROUTE (obj);
|
||||
|
||||
/* return whether @obj is considered a default-route, that is, a route
|
||||
* as added by NetworkManager. E.g. if the route is not in the main-table,
|
||||
* it's considered just like a regular route. */
|
||||
return r
|
||||
&& !r->table_coerced
|
||||
&& NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r);
|
||||
}
|
||||
|
||||
const NMPObject *_nm_ip_config_best_default_route_find_better (const NMPObject *obj_cur, const NMPObject *obj_cmp);
|
||||
gboolean _nm_ip_config_best_default_route_set (const NMPObject **best_default_route, const NMPObject *new_candidate);
|
||||
gboolean _nm_ip_config_best_default_route_merge (const NMPObject **best_default_route, const NMPObject *new_candidate);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean nm_ip_config_obj_id_equal_ip4_address (const NMPlatformIP4Address *a,
|
||||
const NMPlatformIP4Address *b);
|
||||
gboolean nm_ip_config_obj_id_equal_ip6_address (const NMPlatformIP6Address *a,
|
||||
|
|
@ -163,6 +182,9 @@ gboolean nm_ip4_config_has_gateway (const NMIP4Config *self);
|
|||
guint32 nm_ip4_config_get_gateway (const NMIP4Config *self);
|
||||
gint64 nm_ip4_config_get_route_metric (const NMIP4Config *self);
|
||||
|
||||
const NMPObject *nm_ip4_config_best_default_route_get (const NMIP4Config *self);
|
||||
const NMPObject *_nm_ip4_config_best_default_route_find (const NMIP4Config *self);
|
||||
|
||||
const NMDedupMultiHeadEntry *nm_ip4_config_lookup_addresses (const NMIP4Config *self);
|
||||
void nm_ip4_config_reset_addresses (NMIP4Config *self);
|
||||
void nm_ip4_config_add_address (NMIP4Config *self, const NMPlatformIP4Address *address);
|
||||
|
|
@ -234,6 +256,11 @@ NMIPConfigSource nm_ip4_config_get_mtu_source (const NMIP4Config *self);
|
|||
void nm_ip4_config_set_metered (NMIP4Config *self, gboolean metered);
|
||||
gboolean nm_ip4_config_get_metered (const NMIP4Config *self);
|
||||
|
||||
const NMPObject *nm_ip4_config_nmpobj_lookup (const NMIP4Config *self,
|
||||
const NMPObject *needle);
|
||||
gboolean nm_ip4_config_nmpobj_remove (NMIP4Config *self,
|
||||
const NMPObject *needle);
|
||||
|
||||
void nm_ip4_config_hash (const NMIP4Config *self, GChecksum *sum, gboolean dns_only);
|
||||
gboolean nm_ip4_config_equal (const NMIP4Config *a, const NMIP4Config *b);
|
||||
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ typedef struct {
|
|||
GVariant *route_data_variant;
|
||||
GVariant *routes_variant;
|
||||
NMDedupMultiIndex *multi_idx;
|
||||
const NMPObject *best_default_route;
|
||||
union {
|
||||
NMIPConfigDedupMultiIdxType idx_ip6_addresses_;
|
||||
NMDedupMultiIdxType idx_ip6_addresses;
|
||||
|
|
@ -177,6 +178,29 @@ nm_ip_config_iter_ip6_route_init (NMDedupMultiIter *ipconf_iter, const NMIP6Conf
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
const NMPObject *
|
||||
nm_ip6_config_best_default_route_get (const NMIP6Config *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_IP6_CONFIG (self), NULL);
|
||||
|
||||
return NM_IP6_CONFIG_GET_PRIVATE (self)->best_default_route;
|
||||
}
|
||||
|
||||
const NMPObject *
|
||||
_nm_ip6_config_best_default_route_find (const NMIP6Config *self)
|
||||
{
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPObject *new_best_default_route = NULL;
|
||||
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, self, NULL) {
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route,
|
||||
ipconf_iter.current->obj);
|
||||
}
|
||||
return new_best_default_route;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_notify_addresses (NMIP6Config *self)
|
||||
{
|
||||
|
|
@ -193,6 +217,7 @@ _notify_routes (NMIP6Config *self)
|
|||
{
|
||||
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (priv->best_default_route == _nm_ip6_config_best_default_route_find (self));
|
||||
nm_clear_g_variant (&priv->route_data_variant);
|
||||
nm_clear_g_variant (&priv->routes_variant);
|
||||
_notify (self, PROP_ROUTE_DATA);
|
||||
|
|
@ -478,8 +503,6 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
continue;
|
||||
if (route->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL)
|
||||
continue;
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
continue;
|
||||
_add_route (self, plobj, NULL, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -781,8 +804,7 @@ nm_ip6_config_create_setting (const NMIP6Config *self)
|
|||
if (IN6_IS_ADDR_LINKLOCAL (&route->network))
|
||||
continue;
|
||||
|
||||
/* Ignore default route. */
|
||||
if (!route->plen)
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
continue;
|
||||
|
||||
/* Ignore routes provided by external sources */
|
||||
|
|
@ -857,10 +879,8 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFl
|
|||
|
||||
/* routes */
|
||||
if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
|
||||
const NMPlatformIP6Route *route;
|
||||
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, &route)
|
||||
_add_route (dst, NMP_OBJECT_UP_CAST (route), NULL, NULL);
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, NULL)
|
||||
_add_route (dst, ipconf_iter.current->obj, NULL, NULL);
|
||||
}
|
||||
|
||||
if (dst_priv->route_metric == -1)
|
||||
|
|
@ -997,6 +1017,7 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src)
|
|||
NMDedupMultiIter ipconf_iter;
|
||||
const struct in6_addr *dst_tmp, *src_tmp;
|
||||
gboolean changed;
|
||||
gboolean changed_default_route;
|
||||
|
||||
g_return_if_fail (src != NULL);
|
||||
g_return_if_fail (dst != NULL);
|
||||
|
|
@ -1037,12 +1058,24 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src)
|
|||
|
||||
/* routes */
|
||||
changed = FALSE;
|
||||
changed_default_route = FALSE;
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, &r) {
|
||||
nm_auto_nmpobj const NMPObject *obj_old = NULL;
|
||||
|
||||
if (nm_dedup_multi_index_remove_obj (dst_priv->multi_idx,
|
||||
&dst_priv->idx_ip6_routes,
|
||||
NMP_OBJECT_UP_CAST (r),
|
||||
NULL))
|
||||
(gconstpointer *) &obj_old)) {
|
||||
if (dst_priv->best_default_route == obj_old) {
|
||||
nm_clear_nmp_object (&dst_priv->best_default_route);
|
||||
changed_default_route = TRUE;
|
||||
}
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
if (changed_default_route) {
|
||||
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route,
|
||||
_nm_ip6_config_best_default_route_find (dst));
|
||||
}
|
||||
if (changed)
|
||||
_notify_routes (dst);
|
||||
|
|
@ -1088,6 +1121,7 @@ nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src)
|
|||
const NMPlatformIP6Address *a;
|
||||
const NMPlatformIP6Route *r;
|
||||
gboolean changed;
|
||||
const NMPObject *new_best_default_route;
|
||||
|
||||
g_return_if_fail (src);
|
||||
g_return_if_fail (dst);
|
||||
|
|
@ -1128,17 +1162,24 @@ nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src)
|
|||
|
||||
/* routes */
|
||||
changed = FALSE;
|
||||
new_best_default_route = NULL;
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, dst, &r) {
|
||||
const NMPObject *o = NMP_OBJECT_UP_CAST (r);
|
||||
|
||||
if (nm_dedup_multi_index_lookup_obj (src_priv->multi_idx,
|
||||
&src_priv->idx_ip6_routes,
|
||||
NMP_OBJECT_UP_CAST (r)))
|
||||
o)) {
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, o);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nm_dedup_multi_index_remove_entry (dst_priv->multi_idx,
|
||||
ipconf_iter.current) != 1)
|
||||
nm_assert_not_reached ();
|
||||
changed = TRUE;
|
||||
}
|
||||
if (_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route))
|
||||
nm_assert (changed);
|
||||
if (changed)
|
||||
_notify_routes (dst);
|
||||
|
||||
|
|
@ -1175,6 +1216,7 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
|
|||
const NMIP6ConfigPrivate *src_priv;
|
||||
NMDedupMultiIter ipconf_iter_src, ipconf_iter_dst;
|
||||
const NMDedupMultiHeadEntry *head_entry_src;
|
||||
const NMPObject *new_best_default_route;
|
||||
|
||||
g_return_val_if_fail (NM_IS_IP6_CONFIG (src), FALSE);
|
||||
g_return_val_if_fail (NM_IS_IP6_CONFIG (dst), FALSE);
|
||||
|
|
@ -1293,19 +1335,25 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
|
|||
}
|
||||
if (!are_equal) {
|
||||
has_minor_changes = TRUE;
|
||||
new_best_default_route = NULL;
|
||||
nm_dedup_multi_index_dirty_set_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_routes);
|
||||
nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) {
|
||||
const NMPObject *o = ipconf_iter_src.current->obj;
|
||||
const NMPObject *obj_new;
|
||||
|
||||
_nm_ip_config_add_obj (dst_priv->multi_idx,
|
||||
&dst_priv->idx_ip6_routes_,
|
||||
dst_priv->ifindex,
|
||||
ipconf_iter_src.current->obj,
|
||||
o,
|
||||
NULL,
|
||||
FALSE,
|
||||
TRUE,
|
||||
NULL,
|
||||
NULL);
|
||||
&obj_new);
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
|
||||
}
|
||||
nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_routes, FALSE);
|
||||
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route);
|
||||
_notify_routes (dst);
|
||||
}
|
||||
|
||||
|
|
@ -1631,18 +1679,12 @@ nm_ip6_config_add_address (NMIP6Config *self, const NMPlatformIP6Address *new)
|
|||
void
|
||||
_nmtst_ip6_config_del_address (NMIP6Config *self, guint i)
|
||||
{
|
||||
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
const NMPlatformIP6Address *a;
|
||||
|
||||
a = _nmtst_ip6_config_get_address (self, i);
|
||||
g_return_if_fail (a);
|
||||
|
||||
if (nm_dedup_multi_index_remove_obj (priv->multi_idx,
|
||||
&priv->idx_ip6_addresses,
|
||||
NMP_OBJECT_UP_CAST (a),
|
||||
NULL) != 1)
|
||||
g_return_if_reached ();
|
||||
_notify_addresses (self);
|
||||
if (!nm_ip6_config_nmpobj_remove (self,
|
||||
NMP_OBJECT_UP_CAST (a)))
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
guint
|
||||
|
|
@ -1767,6 +1809,7 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
|
|||
NMIP6ConfigPrivate *priv;
|
||||
guint i;
|
||||
gboolean changed = FALSE;
|
||||
const NMPObject *new_best_default_route;
|
||||
|
||||
g_return_if_fail (NM_IS_IP6_CONFIG (self));
|
||||
|
||||
|
|
@ -1776,9 +1819,11 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
|
|||
|
||||
nm_dedup_multi_index_dirty_set_idx (priv->multi_idx, &priv->idx_ip6_routes);
|
||||
|
||||
new_best_default_route = NULL;
|
||||
for (i = 0; i < routes_n; i++) {
|
||||
const NMNDiscRoute *ndisc_route = &routes[i];
|
||||
NMPObject obj;
|
||||
const NMPObject *obj_new;
|
||||
NMPlatformIP6Route *r;
|
||||
|
||||
nmp_object_stackinit (&obj, NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
|
||||
|
|
@ -1798,10 +1843,14 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
|
|||
FALSE,
|
||||
TRUE,
|
||||
NULL,
|
||||
NULL))
|
||||
&obj_new))
|
||||
changed = TRUE;
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
|
||||
}
|
||||
|
||||
if (_nm_ip_config_best_default_route_set (&priv->best_default_route, new_best_default_route))
|
||||
changed = TRUE;
|
||||
|
||||
if (nm_dedup_multi_index_dirty_remove_idx (priv->multi_idx, &priv->idx_ip6_routes, FALSE) > 0)
|
||||
changed = TRUE;
|
||||
|
||||
|
|
@ -1815,8 +1864,10 @@ nm_ip6_config_reset_routes (NMIP6Config *self)
|
|||
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
if (nm_dedup_multi_index_remove_idx (priv->multi_idx,
|
||||
&priv->idx_ip6_routes) > 0)
|
||||
&priv->idx_ip6_routes) > 0) {
|
||||
nm_clear_nmp_object (&priv->best_default_route);
|
||||
_notify_routes (self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1826,6 +1877,7 @@ _add_route (NMIP6Config *self,
|
|||
const NMPObject **out_obj_new)
|
||||
{
|
||||
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
nm_auto_nmpobj const NMPObject *obj_old = NULL;
|
||||
const NMPObject *obj_new_2;
|
||||
|
||||
nm_assert ((!new) != (!obj_new));
|
||||
|
|
@ -1839,8 +1891,12 @@ _add_route (NMIP6Config *self,
|
|||
(const NMPlatformObject *) new,
|
||||
TRUE,
|
||||
FALSE,
|
||||
NULL,
|
||||
&obj_old,
|
||||
&obj_new_2)) {
|
||||
if ( priv->best_default_route == obj_old
|
||||
&& obj_old != obj_new_2)
|
||||
nm_clear_nmp_object (&priv->best_default_route);
|
||||
_nm_ip_config_best_default_route_merge (&priv->best_default_route, obj_new_2);
|
||||
NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2));
|
||||
_notify_routes (self);
|
||||
} else
|
||||
|
|
@ -1866,7 +1922,7 @@ nm_ip6_config_add_route (NMIP6Config *self,
|
|||
{
|
||||
g_return_if_fail (self);
|
||||
g_return_if_fail (new);
|
||||
g_return_if_fail (new->plen > 0 && new->plen <= 128);
|
||||
g_return_if_fail (new->plen <= 128);
|
||||
g_return_if_fail (NM_IP6_CONFIG_GET_PRIVATE (self)->ifindex > 0);
|
||||
|
||||
_add_route (self, NULL, new, out_obj_new);
|
||||
|
|
@ -1875,18 +1931,12 @@ nm_ip6_config_add_route (NMIP6Config *self,
|
|||
void
|
||||
_nmtst_ip6_config_del_route (NMIP6Config *self, guint i)
|
||||
{
|
||||
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
const NMPlatformIP6Route *r;
|
||||
|
||||
r = _nmtst_ip6_config_get_route (self, i);
|
||||
g_return_if_fail (r);
|
||||
|
||||
if (nm_dedup_multi_index_remove_obj (priv->multi_idx,
|
||||
&priv->idx_ip6_routes,
|
||||
NMP_OBJECT_UP_CAST (r),
|
||||
NULL) != 1)
|
||||
g_return_if_reached ();
|
||||
_notify_routes (self);
|
||||
if (!nm_ip6_config_nmpobj_remove (self,
|
||||
NMP_OBJECT_UP_CAST (r)))
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
guint
|
||||
|
|
@ -2251,6 +2301,84 @@ nm_ip6_config_get_mss (const NMIP6Config *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
const NMPObject *
|
||||
nm_ip6_config_nmpobj_lookup (const NMIP6Config *self, const NMPObject *needle)
|
||||
{
|
||||
const NMIP6ConfigPrivate *priv;
|
||||
const NMDedupMultiIdxType *idx_type;
|
||||
|
||||
g_return_val_if_fail (NM_IS_IP6_CONFIG (self), NULL);
|
||||
|
||||
priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
switch (NMP_OBJECT_GET_TYPE (needle)) {
|
||||
case NMP_OBJECT_TYPE_IP6_ADDRESS:
|
||||
idx_type = &priv->idx_ip6_addresses;
|
||||
break;
|
||||
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
||||
idx_type = &priv->idx_ip6_routes;
|
||||
break;
|
||||
default:
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
return nm_dedup_multi_entry_get_obj (nm_dedup_multi_index_lookup_obj (priv->multi_idx,
|
||||
idx_type,
|
||||
needle));
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_ip6_config_nmpobj_remove (NMIP6Config *self,
|
||||
const NMPObject *needle)
|
||||
{
|
||||
NMIP6ConfigPrivate *priv;
|
||||
NMDedupMultiIdxType *idx_type;
|
||||
nm_auto_nmpobj const NMPObject *obj_old = NULL;
|
||||
guint n;
|
||||
|
||||
g_return_val_if_fail (NM_IS_IP6_CONFIG (self), FALSE);
|
||||
|
||||
priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
switch (NMP_OBJECT_GET_TYPE (needle)) {
|
||||
case NMP_OBJECT_TYPE_IP6_ADDRESS:
|
||||
idx_type = &priv->idx_ip6_addresses;
|
||||
break;
|
||||
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
||||
idx_type = &priv->idx_ip6_routes;
|
||||
break;
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
n = nm_dedup_multi_index_remove_obj (priv->multi_idx,
|
||||
idx_type,
|
||||
needle,
|
||||
(gconstpointer *) &obj_old);
|
||||
if (n != 1) {
|
||||
nm_assert (n == 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nm_assert (NMP_OBJECT_GET_TYPE (obj_old) == NMP_OBJECT_GET_TYPE (needle));
|
||||
|
||||
switch (NMP_OBJECT_GET_TYPE (obj_old)) {
|
||||
case NMP_OBJECT_TYPE_IP6_ADDRESS:
|
||||
_notify_addresses (self);
|
||||
break;
|
||||
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
||||
if (priv->best_default_route == obj_old) {
|
||||
_nm_ip_config_best_default_route_set (&priv->best_default_route,
|
||||
_nm_ip6_config_best_default_route_find (self));
|
||||
}
|
||||
_notify_routes (self);
|
||||
break;
|
||||
default:
|
||||
nm_assert_not_reached ();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline void
|
||||
hash_u32 (GChecksum *sum, guint32 n)
|
||||
{
|
||||
|
|
@ -2611,6 +2739,8 @@ finalize (GObject *object)
|
|||
NMIP6Config *self = NM_IP6_CONFIG (object);
|
||||
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
nm_clear_nmp_object (&priv->best_default_route);
|
||||
|
||||
nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip6_addresses);
|
||||
nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip6_routes);
|
||||
|
||||
|
|
|
|||
|
|
@ -127,6 +127,9 @@ void nm_ip6_config_set_gateway (NMIP6Config *self, const struct in6_addr *);
|
|||
const struct in6_addr *nm_ip6_config_get_gateway (const NMIP6Config *self);
|
||||
gint64 nm_ip6_config_get_route_metric (const NMIP6Config *self);
|
||||
|
||||
const NMPObject *nm_ip6_config_best_default_route_get (const NMIP6Config *self);
|
||||
const NMPObject *_nm_ip6_config_best_default_route_find (const NMIP6Config *self);
|
||||
|
||||
const NMDedupMultiHeadEntry *nm_ip6_config_lookup_addresses (const NMIP6Config *self);
|
||||
void nm_ip6_config_reset_addresses (NMIP6Config *self);
|
||||
void nm_ip6_config_add_address (NMIP6Config *self, const NMPlatformIP6Address *address);
|
||||
|
|
@ -184,6 +187,11 @@ gint nm_ip6_config_get_dns_priority (const NMIP6Config *self);
|
|||
void nm_ip6_config_set_mss (NMIP6Config *self, guint32 mss);
|
||||
guint32 nm_ip6_config_get_mss (const NMIP6Config *self);
|
||||
|
||||
const NMPObject *nm_ip6_config_nmpobj_lookup (const NMIP6Config *self,
|
||||
const NMPObject *needle);
|
||||
gboolean nm_ip6_config_nmpobj_remove (NMIP6Config *self,
|
||||
const NMPObject *needle);
|
||||
|
||||
void nm_ip6_config_hash (const NMIP6Config *self, GChecksum *sum, gboolean dns_only);
|
||||
gboolean nm_ip6_config_equal (const NMIP6Config *a, const NMIP6Config *b);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "platform/nm-platform.h"
|
||||
#include "platform/nmp-netns.h"
|
||||
#include "nm-default-route-manager.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
|
|
@ -39,7 +38,6 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
|
|||
typedef struct {
|
||||
NMPlatform *platform;
|
||||
NMPNetns *platform_netns;
|
||||
NMDefaultRouteManager *default_route_manager;
|
||||
bool log_with_ptr;
|
||||
} NMNetnsPrivate;
|
||||
|
||||
|
|
@ -80,12 +78,6 @@ nm_netns_get_multi_idx (NMNetns *self)
|
|||
return nm_platform_get_multi_idx (NM_NETNS_GET_PRIVATE (self)->platform);
|
||||
}
|
||||
|
||||
NMDefaultRouteManager *
|
||||
nm_netns_get_default_route_manager (NMNetns *self)
|
||||
{
|
||||
return NM_NETNS_GET_PRIVATE (self)->default_route_manager;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -129,7 +121,6 @@ constructed (GObject *object)
|
|||
log_with_ptr = nm_platform_get_log_with_ptr (priv->platform);
|
||||
|
||||
priv->platform_netns = nm_platform_netns_get (priv->platform);
|
||||
priv->default_route_manager = nm_default_route_manager_new (log_with_ptr, priv->platform);
|
||||
|
||||
G_OBJECT_CLASS (nm_netns_parent_class)->constructed (object);
|
||||
}
|
||||
|
|
@ -148,7 +139,6 @@ dispose (GObject *object)
|
|||
NMNetns *self = NM_NETNS (object);
|
||||
NMNetnsPrivate *priv = NM_NETNS_GET_PRIVATE (self);
|
||||
|
||||
g_clear_object (&priv->default_route_manager);
|
||||
g_clear_object (&priv->platform);
|
||||
|
||||
G_OBJECT_CLASS (nm_netns_parent_class)->dispose (object);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ NMNetns *nm_netns_new (NMPlatform *platform);
|
|||
|
||||
NMPlatform *nm_netns_get_platform (NMNetns *self);
|
||||
NMPNetns *nm_netns_get_platform_netns (NMNetns *self);
|
||||
NMDefaultRouteManager *nm_netns_get_default_route_manager (NMNetns *self);
|
||||
|
||||
struct _NMDedupMultiIndex *nm_netns_get_multi_idx (NMNetns *self);
|
||||
|
||||
|
|
|
|||
|
|
@ -192,6 +192,8 @@ get_ip4_domains (GPtrArray *domains, NMIP4Config *ip4)
|
|||
}
|
||||
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &routes) {
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (routes))
|
||||
continue;
|
||||
cidr = g_strdup_printf ("%s/%u",
|
||||
nm_utils_inet4_ntop (routes->network, NULL),
|
||||
routes->plen);
|
||||
|
|
@ -225,6 +227,8 @@ get_ip6_domains (GPtrArray *domains, NMIP6Config *ip6)
|
|||
}
|
||||
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &routes) {
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (routes))
|
||||
continue;
|
||||
cidr = g_strdup_printf ("%s/%u",
|
||||
nm_utils_inet6_ntop (&routes->network, NULL),
|
||||
routes->plen);
|
||||
|
|
|
|||
202
src/nm-policy.c
202
src/nm-policy.c
|
|
@ -31,7 +31,6 @@
|
|||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-act-request.h"
|
||||
#include "devices/nm-device.h"
|
||||
#include "nm-default-route-manager.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "platform/nm-platform.h"
|
||||
|
|
@ -375,25 +374,81 @@ device_ip6_subnet_needed (NMDevice *device,
|
|||
/*****************************************************************************/
|
||||
|
||||
static NMDevice *
|
||||
get_best_ip4_device (NMPolicy *self, gboolean fully_activated)
|
||||
get_best_ip_device (NMPolicy *self,
|
||||
int addr_family,
|
||||
gboolean fully_activated)
|
||||
{
|
||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||
const GSList *iter;
|
||||
NMDevice *best_device;
|
||||
NMDevice *prev_device;
|
||||
guint32 best_metric = G_MAXUINT32;
|
||||
gboolean best_is_fully_activated = FALSE;
|
||||
|
||||
return nm_default_route_manager_ip4_get_best_device (nm_netns_get_default_route_manager (priv->netns),
|
||||
nm_manager_get_devices (priv->manager),
|
||||
fully_activated,
|
||||
priv->default_device4);
|
||||
}
|
||||
nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
|
||||
|
||||
static NMDevice *
|
||||
get_best_ip6_device (NMPolicy *self, gboolean fully_activated)
|
||||
{
|
||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||
/* we prefer the current device in case of identical metric.
|
||||
* Hence, try that one first.*/
|
||||
best_device = NULL;
|
||||
prev_device = addr_family == AF_INET
|
||||
? (fully_activated ? priv->default_device4 : priv->activating_device4)
|
||||
: (fully_activated ? priv->default_device6 : priv->activating_device6);
|
||||
|
||||
return nm_default_route_manager_ip6_get_best_device (nm_netns_get_default_route_manager (priv->netns),
|
||||
nm_manager_get_devices (priv->manager),
|
||||
fully_activated,
|
||||
priv->default_device6);
|
||||
for (iter = nm_manager_get_devices (priv->manager); iter; iter = iter->next) {
|
||||
NMDevice *device = NM_DEVICE (iter->data);
|
||||
NMDeviceState state;
|
||||
const NMPObject *r;
|
||||
NMConnection *connection;
|
||||
guint32 metric;
|
||||
gboolean is_fully_activated;
|
||||
|
||||
state = nm_device_get_state (device);
|
||||
if ( state <= NM_DEVICE_STATE_DISCONNECTED
|
||||
|| state >= NM_DEVICE_STATE_DEACTIVATING)
|
||||
continue;
|
||||
|
||||
if (nm_device_sys_iface_state_is_external (device))
|
||||
continue;
|
||||
|
||||
r = nm_device_get_best_default_route (device, addr_family);
|
||||
if (r) {
|
||||
/* XXX: the best route might have rt_source NM_IP_CONFIG_SOURCE_VPN,
|
||||
* which means it was injected by a VPN, not added by device.
|
||||
*
|
||||
* In this case, is it really the best device? Why do we even need the best
|
||||
* device?? */
|
||||
metric = nm_utils_ip_route_metric_normalize (addr_family,
|
||||
NMP_OBJECT_CAST_IP_ROUTE (r)->metric);
|
||||
is_fully_activated = TRUE;
|
||||
} else if ( !fully_activated
|
||||
&& (connection = nm_device_get_applied_connection (device))
|
||||
&& nm_utils_connection_has_default_route (connection, addr_family, NULL)) {
|
||||
metric = nm_utils_ip_route_metric_normalize (addr_family,
|
||||
nm_device_get_ip_route_metric (device, addr_family));
|
||||
is_fully_activated = FALSE;
|
||||
} else
|
||||
continue;
|
||||
|
||||
if ( !best_device
|
||||
|| (!best_is_fully_activated && is_fully_activated)
|
||||
|| ( metric < best_metric
|
||||
|| (metric == best_metric && device == prev_device))) {
|
||||
best_device = device;
|
||||
best_metric = metric;
|
||||
best_is_fully_activated = is_fully_activated;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !fully_activated
|
||||
&& best_device
|
||||
&& best_is_fully_activated) {
|
||||
/* There's only a best activating device if the best device
|
||||
* among all activating and already-activated devices is a
|
||||
* still-activating one. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return best_device;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -782,20 +837,83 @@ update_default_ac (NMPolicy *self,
|
|||
set_active_func (best, TRUE);
|
||||
}
|
||||
|
||||
static NMIP4Config *
|
||||
get_best_ip4_config (NMPolicy *self,
|
||||
gboolean ignore_never_default,
|
||||
const char **out_ip_iface,
|
||||
NMActiveConnection **out_ac,
|
||||
NMDevice **out_device,
|
||||
NMVpnConnection **out_vpn)
|
||||
static gpointer
|
||||
get_best_ip_config (NMPolicy *self,
|
||||
int addr_family,
|
||||
const char **out_ip_iface,
|
||||
NMActiveConnection **out_ac,
|
||||
NMDevice **out_device,
|
||||
NMVpnConnection **out_vpn)
|
||||
{
|
||||
return nm_default_route_manager_ip4_get_best_config (nm_netns_get_default_route_manager (NM_POLICY_GET_PRIVATE (self)->netns),
|
||||
ignore_never_default,
|
||||
out_ip_iface,
|
||||
out_ac,
|
||||
out_device,
|
||||
out_vpn);
|
||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||
NMDevice *device;
|
||||
gpointer conf;
|
||||
const GSList *iter;
|
||||
|
||||
nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
|
||||
|
||||
for (iter = nm_manager_get_active_connections (priv->manager); iter; iter = iter->next) {
|
||||
NMActiveConnection *active = NM_ACTIVE_CONNECTION (iter->data);
|
||||
NMVpnConnection *candidate;
|
||||
NMVpnConnectionState vpn_state;
|
||||
|
||||
if (!NM_IS_VPN_CONNECTION (active))
|
||||
continue;
|
||||
|
||||
candidate = NM_VPN_CONNECTION (active);
|
||||
|
||||
vpn_state = nm_vpn_connection_get_vpn_state (candidate);
|
||||
if (vpn_state != NM_VPN_CONNECTION_STATE_ACTIVATED)
|
||||
continue;
|
||||
|
||||
if (addr_family == AF_INET)
|
||||
conf = nm_vpn_connection_get_ip4_config (candidate);
|
||||
else
|
||||
conf = nm_vpn_connection_get_ip6_config (candidate);
|
||||
if (!conf)
|
||||
continue;
|
||||
|
||||
if (addr_family == AF_INET) {
|
||||
if (!nm_ip4_config_best_default_route_get (conf))
|
||||
continue;
|
||||
} else {
|
||||
if (!nm_ip6_config_best_default_route_get (conf))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* FIXME: in case of multiple VPN candidates, choose the one with the
|
||||
* best metric. */
|
||||
NM_SET_OUT (out_device, NULL);
|
||||
NM_SET_OUT (out_vpn, candidate);
|
||||
NM_SET_OUT (out_ac, active);
|
||||
NM_SET_OUT (out_ip_iface, nm_vpn_connection_get_ip_iface (candidate, TRUE));
|
||||
return conf;
|
||||
}
|
||||
|
||||
device = get_best_ip_device (self, addr_family, TRUE);
|
||||
if (device) {
|
||||
NMActRequest *req;
|
||||
|
||||
if (addr_family == AF_INET)
|
||||
conf = nm_device_get_ip4_config (device);
|
||||
else
|
||||
conf = nm_device_get_ip6_config (device);
|
||||
req = nm_device_get_act_request (device);
|
||||
|
||||
if (conf && req) {
|
||||
NM_SET_OUT (out_device, device);
|
||||
NM_SET_OUT (out_vpn, NULL);
|
||||
NM_SET_OUT (out_ac, NM_ACTIVE_CONNECTION (req));
|
||||
NM_SET_OUT (out_ip_iface, nm_device_get_ip_iface (device));
|
||||
return conf;
|
||||
}
|
||||
}
|
||||
|
||||
NM_SET_OUT (out_device, NULL);
|
||||
NM_SET_OUT (out_vpn, NULL);
|
||||
NM_SET_OUT (out_ac, NULL);
|
||||
NM_SET_OUT (out_ip_iface, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -806,7 +924,7 @@ update_ip4_dns (NMPolicy *self, NMDnsManager *dns_mgr)
|
|||
NMVpnConnection *vpn = NULL;
|
||||
NMDnsIPConfigType dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE;
|
||||
|
||||
ip4_config = get_best_ip4_config (self, TRUE, &ip_iface, NULL, NULL, &vpn);
|
||||
ip4_config = get_best_ip_config (self, AF_INET, &ip_iface, NULL, NULL, &vpn);
|
||||
if (ip4_config) {
|
||||
if (vpn)
|
||||
dns_type = NM_DNS_IP_CONFIG_TYPE_VPN;
|
||||
|
|
@ -830,7 +948,7 @@ update_ip4_routing (NMPolicy *self, gboolean force_update)
|
|||
/* Note that we might have an IPv4 VPN tunneled over an IPv6-only device,
|
||||
* so we can get (vpn != NULL && best == NULL).
|
||||
*/
|
||||
if (!get_best_ip4_config (self, FALSE, &ip_iface, &best_ac, &best, &vpn)) {
|
||||
if (!get_best_ip_config (self, AF_INET, &ip_iface, &best_ac, &best, &vpn)) {
|
||||
if (nm_clear_g_object (&priv->default_device4)) {
|
||||
_LOGt (LOGD_DNS, "set-default-device-4: %p", NULL);
|
||||
_notify (self, PROP_DEFAULT_IP4_DEVICE);
|
||||
|
|
@ -873,22 +991,6 @@ update_ip4_routing (NMPolicy *self, gboolean force_update)
|
|||
_notify (self, PROP_DEFAULT_IP4_DEVICE);
|
||||
}
|
||||
|
||||
static NMIP6Config *
|
||||
get_best_ip6_config (NMPolicy *self,
|
||||
gboolean ignore_never_default,
|
||||
const char **out_ip_iface,
|
||||
NMActiveConnection **out_ac,
|
||||
NMDevice **out_device,
|
||||
NMVpnConnection **out_vpn)
|
||||
{
|
||||
return nm_default_route_manager_ip6_get_best_config (nm_netns_get_default_route_manager (NM_POLICY_GET_PRIVATE (self)->netns),
|
||||
ignore_never_default,
|
||||
out_ip_iface,
|
||||
out_ac,
|
||||
out_device,
|
||||
out_vpn);
|
||||
}
|
||||
|
||||
static void
|
||||
update_ip6_dns_delegation (NMPolicy *self)
|
||||
{
|
||||
|
|
@ -912,7 +1014,7 @@ update_ip6_dns (NMPolicy *self, NMDnsManager *dns_mgr)
|
|||
NMVpnConnection *vpn = NULL;
|
||||
NMDnsIPConfigType dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE;
|
||||
|
||||
ip6_config = get_best_ip6_config (self, TRUE, &ip_iface, NULL, NULL, &vpn);
|
||||
ip6_config = get_best_ip_config (self, AF_INET6, &ip_iface, NULL, NULL, &vpn);
|
||||
if (ip6_config) {
|
||||
if (vpn)
|
||||
dns_type = NM_DNS_IP_CONFIG_TYPE_VPN;
|
||||
|
|
@ -954,7 +1056,7 @@ update_ip6_routing (NMPolicy *self, gboolean force_update)
|
|||
/* Note that we might have an IPv6 VPN tunneled over an IPv4-only device,
|
||||
* so we can get (vpn != NULL && best == NULL).
|
||||
*/
|
||||
if (!get_best_ip6_config (self, FALSE, &ip_iface, &best_ac, &best, &vpn)) {
|
||||
if (!get_best_ip_config (self, AF_INET6, &ip_iface, &best_ac, &best, &vpn)) {
|
||||
if (nm_clear_g_object (&priv->default_device6)) {
|
||||
_LOGt (LOGD_DNS, "set-default-device-6: %p", NULL);
|
||||
_notify (self, PROP_DEFAULT_IP6_DEVICE);
|
||||
|
|
@ -1024,8 +1126,8 @@ check_activating_devices (NMPolicy *self)
|
|||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||
NMDevice *best4, *best6 = NULL;
|
||||
|
||||
best4 = get_best_ip4_device (self, FALSE);
|
||||
best6 = get_best_ip6_device (self, FALSE);
|
||||
best4 = get_best_ip_device (self, AF_INET, FALSE);
|
||||
best6 = get_best_ip_device (self, AF_INET6, FALSE);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (self));
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ typedef struct _NMConfigData NMConfigData;
|
|||
typedef struct _NMArpingManager NMArpingManager;
|
||||
typedef struct _NMConnectionProvider NMConnectionProvider;
|
||||
typedef struct _NMConnectivity NMConnectivity;
|
||||
typedef struct _NMDefaultRouteManager NMDefaultRouteManager;
|
||||
typedef struct _NMDevice NMDevice;
|
||||
typedef struct _NMDhcp4Config NMDhcp4Config;
|
||||
typedef struct _NMDhcp6Config NMDhcp6Config;
|
||||
|
|
|
|||
|
|
@ -3697,11 +3697,6 @@ nm_platform_ip_route_sync (NMPlatform *self,
|
|||
for (i = 0; i < plat_routes->len; i++) {
|
||||
plat_o = plat_routes->pdata[i];
|
||||
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (NMP_OBJECT_CAST_IP_ROUTE (plat_o))) {
|
||||
/* don't delete default routes. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !routes_idx
|
||||
|| !g_hash_table_lookup (routes_idx, plat_o)) {
|
||||
if (!nm_platform_ip_route_delete (self, plat_o)) {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@
|
|||
#include "settings/nm-agent-manager.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-pacrunner-manager.h"
|
||||
#include "nm-default-route-manager.h"
|
||||
#include "nm-firewall-manager.h"
|
||||
#include "nm-config.h"
|
||||
#include "nm-vpn-plugin-info.h"
|
||||
|
|
@ -498,9 +497,6 @@ _set_vpn_state (NMVpnConnection *self,
|
|||
|
||||
dispatcher_cleanup (self);
|
||||
|
||||
nm_default_route_manager_ip4_update_default_route (nm_netns_get_default_route_manager (priv->netns), self);
|
||||
nm_default_route_manager_ip6_update_default_route (nm_netns_get_default_route_manager (priv->netns), self);
|
||||
|
||||
/* The connection gets destroyed by the VPN manager when it enters the
|
||||
* disconnected/failed state, but we need to keep it around for a bit
|
||||
* to send out signals and handle the dispatcher. So ref it.
|
||||
|
|
@ -1167,9 +1163,6 @@ nm_vpn_connection_apply_config (NMVpnConnection *self)
|
|||
nm_platform_link_set_mtu (nm_netns_get_platform (priv->netns), priv->ip_ifindex, priv->mtu);
|
||||
}
|
||||
|
||||
nm_default_route_manager_ip4_update_default_route (nm_netns_get_default_route_manager (priv->netns), self);
|
||||
nm_default_route_manager_ip6_update_default_route (nm_netns_get_default_route_manager (priv->netns), self);
|
||||
|
||||
_LOGI ("VPN connection: (IP Config Get) complete");
|
||||
if (priv->vpn_state < STATE_PRE_UP)
|
||||
_set_vpn_state (self, STATE_PRE_UP, NM_ACTIVE_CONNECTION_STATE_REASON_NONE, FALSE);
|
||||
|
|
@ -1596,6 +1589,18 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
|
|||
nm_connection_get_setting_ip4_config (_get_applied_connection (self)),
|
||||
route_metric);
|
||||
|
||||
if (!nm_ip4_config_get_never_default (config)) {
|
||||
const NMPlatformIP4Route r = {
|
||||
.ifindex = ip_ifindex,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_VPN,
|
||||
.gateway = nm_ip4_config_get_gateway (config),
|
||||
.metric = route_metric,
|
||||
.mss = nm_ip4_config_get_mss (config),
|
||||
};
|
||||
|
||||
nm_ip4_config_add_route (config, &r, NULL);
|
||||
}
|
||||
|
||||
if (priv->ip4_config) {
|
||||
nm_ip4_config_replace (priv->ip4_config, config, NULL);
|
||||
g_object_unref (config);
|
||||
|
|
@ -1758,6 +1763,18 @@ next:
|
|||
nm_connection_get_setting_ip6_config (_get_applied_connection (self)),
|
||||
route_metric);
|
||||
|
||||
if (!nm_ip6_config_get_never_default (config)) {
|
||||
const NMPlatformIP6Route r = {
|
||||
.ifindex = ip_ifindex,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_VPN,
|
||||
.gateway = *(nm_ip6_config_get_gateway (config) ?: &in6addr_any),
|
||||
.metric = route_metric,
|
||||
.mss = nm_ip6_config_get_mss (config),
|
||||
};
|
||||
|
||||
nm_ip6_config_add_route (config, &r, NULL);
|
||||
}
|
||||
|
||||
if (priv->ip6_config) {
|
||||
nm_ip6_config_replace (priv->ip6_config, config, NULL);
|
||||
g_object_unref (config);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue