mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-07 13:08:10 +02:00
device,default-route-manager: merge branch 'th/default-route-resync'
(cherry picked from commit 6197c27f24)
This commit is contained in:
commit
bb3b8627a0
2 changed files with 124 additions and 67 deletions
|
|
@ -124,7 +124,7 @@ NM_DEFINE_SINGLETON_GETTER (NMDefaultRouteManager, nm_default_route_manager_get,
|
||||||
const Entry *const __entry = (entry); \
|
const Entry *const __entry = (entry); \
|
||||||
\
|
\
|
||||||
_nm_log (__level, __domain, 0, \
|
_nm_log (__level, __domain, 0, \
|
||||||
"%s: entry[%u/%s:%p:%s:%c:%csync]: "_NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
"%s: entry[%u/%s:%p:%s:%chas:%csync]: "_NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
||||||
self != singleton_instance \
|
self != singleton_instance \
|
||||||
? nm_sprintf_buf (__prefix_buf, "%s%c[%p]", \
|
? nm_sprintf_buf (__prefix_buf, "%s%c[%p]", \
|
||||||
_NMLOG2_PREFIX_NAME, \
|
_NMLOG2_PREFIX_NAME, \
|
||||||
|
|
@ -135,7 +135,7 @@ NM_DEFINE_SINGLETON_GETTER (NMDefaultRouteManager, nm_default_route_manager_get,
|
||||||
NM_IS_DEVICE (__entry->source.pointer) ? "dev" : "vpn", \
|
NM_IS_DEVICE (__entry->source.pointer) ? "dev" : "vpn", \
|
||||||
__entry->source.pointer, \
|
__entry->source.pointer, \
|
||||||
NM_IS_DEVICE (__entry->source.pointer) ? nm_device_get_iface (__entry->source.device) : nm_active_connection_get_settings_connection_id (NM_ACTIVE_CONNECTION (__entry->source.vpn)), \
|
NM_IS_DEVICE (__entry->source.pointer) ? nm_device_get_iface (__entry->source.device) : nm_active_connection_get_settings_connection_id (NM_ACTIVE_CONNECTION (__entry->source.vpn)), \
|
||||||
(__entry->never_default ? '0' : '1'), \
|
(__entry->never_default ? '-' : '+'), \
|
||||||
(__entry->synced ? '+' : '-') \
|
(__entry->synced ? '+' : '-') \
|
||||||
_NM_UTILS_MACRO_REST(__VA_ARGS__)); \
|
_NM_UTILS_MACRO_REST(__VA_ARGS__)); \
|
||||||
} \
|
} \
|
||||||
|
|
@ -483,17 +483,6 @@ _get_assumed_interface_metrics (const VTableIP *vtable, NMDefaultRouteManager *s
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
_sort_metrics_ascending_fcn (gconstpointer a, gconstpointer b)
|
|
||||||
{
|
|
||||||
guint32 m_a = *((guint32 *) a);
|
|
||||||
guint32 m_b = *((guint32 *) b);
|
|
||||||
|
|
||||||
if (m_a < m_b)
|
|
||||||
return -1;
|
|
||||||
return m_a == m_b ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *changed_entry, const Entry *old_entry, gboolean external_change)
|
_resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *changed_entry, const Entry *old_entry, gboolean external_change)
|
||||||
{
|
{
|
||||||
|
|
@ -536,8 +525,6 @@ _resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *c
|
||||||
for (i = 0; i < entries->len; i++) {
|
for (i = 0; i < entries->len; i++) {
|
||||||
entry = g_ptr_array_index (entries, i);
|
entry = g_ptr_array_index (entries, i);
|
||||||
|
|
||||||
g_assert (entry != old_entry);
|
|
||||||
|
|
||||||
if (entry->never_default)
|
if (entry->never_default)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -592,12 +579,15 @@ _resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *c
|
||||||
/* for the changed entry, the previous metric was either old_entry->effective_metric,
|
/* for the changed entry, the previous metric was either old_entry->effective_metric,
|
||||||
* or none. Hence, we only have to remember what is going to change. */
|
* or none. Hence, we only have to remember what is going to change. */
|
||||||
g_array_append_val (changed_metrics, expected_metric);
|
g_array_append_val (changed_metrics, expected_metric);
|
||||||
if (old_entry) {
|
if (!old_entry) {
|
||||||
|
_LOG2D (vtable, i, entry, "sync:add %s (%u)",
|
||||||
|
vtable->vt->route_to_string (&entry->route, NULL, 0), (guint) expected_metric);
|
||||||
|
} else if (old_entry != changed_entry) {
|
||||||
_LOG2D (vtable, i, entry, "sync:update %s (%u -> %u)",
|
_LOG2D (vtable, i, entry, "sync:update %s (%u -> %u)",
|
||||||
vtable->vt->route_to_string (&entry->route, NULL, 0), (guint) old_entry->effective_metric,
|
vtable->vt->route_to_string (&entry->route, NULL, 0), (guint) old_entry->effective_metric,
|
||||||
(guint) expected_metric);
|
(guint) expected_metric);
|
||||||
} else {
|
} else {
|
||||||
_LOG2D (vtable, i, entry, "sync:add %s (%u)",
|
_LOG2D (vtable, i, entry, "sync:resync %s (%u)",
|
||||||
vtable->vt->route_to_string (&entry->route, NULL, 0), (guint) expected_metric);
|
vtable->vt->route_to_string (&entry->route, NULL, 0), (guint) expected_metric);
|
||||||
}
|
}
|
||||||
} else if (entry->effective_metric != expected_metric) {
|
} else if (entry->effective_metric != expected_metric) {
|
||||||
|
|
@ -624,7 +614,7 @@ _resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *c
|
||||||
|
|
||||||
g_array_free (routes, TRUE);
|
g_array_free (routes, TRUE);
|
||||||
|
|
||||||
g_array_sort (changed_metrics, _sort_metrics_ascending_fcn);
|
g_array_sort_with_data (changed_metrics, nm_cmp_uint32_p_with_data, NULL);
|
||||||
last_metric = -1;
|
last_metric = -1;
|
||||||
for (j = 0; j < changed_metrics->len; j++) {
|
for (j = 0; j < changed_metrics->len; j++) {
|
||||||
expected_metric = g_array_index (changed_metrics, guint32, j);
|
expected_metric = g_array_index (changed_metrics, guint32, j);
|
||||||
|
|
@ -675,7 +665,11 @@ _entry_at_idx_update (const VTableIP *vtable, NMDefaultRouteManager *self, guint
|
||||||
entry->effective_metric = entry->route.rx.metric;
|
entry->effective_metric = entry->route.rx.metric;
|
||||||
|
|
||||||
_LOG2D (vtable, entry_idx, entry, "%s %s (%"G_GUINT32_FORMAT")",
|
_LOG2D (vtable, entry_idx, entry, "%s %s (%"G_GUINT32_FORMAT")",
|
||||||
old_entry ? "record:update" : "record:add ",
|
old_entry
|
||||||
|
? (entry != old_entry
|
||||||
|
? "record:update"
|
||||||
|
: "record:resync")
|
||||||
|
: "record:add ",
|
||||||
vtable->vt->route_to_string (&entry->route, NULL, 0),
|
vtable->vt->route_to_string (&entry->route, NULL, 0),
|
||||||
entry->effective_metric);
|
entry->effective_metric);
|
||||||
|
|
||||||
|
|
@ -712,7 +706,9 @@ _entry_at_idx_remove (const VTableIP *vtable, NMDefaultRouteManager *self, guint
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, gpointer source)
|
_ipx_update_default_route (const VTableIP *vtable,
|
||||||
|
NMDefaultRouteManager *self,
|
||||||
|
gpointer source)
|
||||||
{
|
{
|
||||||
NMDefaultRouteManagerPrivate *priv;
|
NMDefaultRouteManagerPrivate *priv;
|
||||||
Entry *entry;
|
Entry *entry;
|
||||||
|
|
@ -784,9 +780,8 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
|
||||||
default_route = &rt.rx;
|
default_route = &rt.rx;
|
||||||
|
|
||||||
never_default = TRUE;
|
never_default = TRUE;
|
||||||
synced = TRUE;
|
}
|
||||||
} else
|
synced = !is_assumed;
|
||||||
synced = default_route && !is_assumed;
|
|
||||||
} else {
|
} else {
|
||||||
NMConnection *connection = nm_active_connection_get_applied_connection ((NMActiveConnection *) vpn);
|
NMConnection *connection = nm_active_connection_get_applied_connection ((NMActiveConnection *) vpn);
|
||||||
|
|
||||||
|
|
@ -878,12 +873,18 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
|
||||||
new_entry.never_default = never_default;
|
new_entry.never_default = never_default;
|
||||||
new_entry.synced = synced;
|
new_entry.synced = synced;
|
||||||
|
|
||||||
if (memcmp (entry, &new_entry, sizeof (new_entry)) == 0)
|
if (memcmp (entry, &new_entry, sizeof (new_entry)) == 0) {
|
||||||
return;
|
if (!synced) {
|
||||||
|
/* the internal book-keeping doesn't change, so don't do a full
|
||||||
old_entry = *entry;
|
* sync of the configured routes. */
|
||||||
*entry = new_entry;
|
return;
|
||||||
_entry_at_idx_update (vtable, self, entry_idx, &old_entry);
|
}
|
||||||
|
_entry_at_idx_update (vtable, self, entry_idx, entry);
|
||||||
|
} else {
|
||||||
|
old_entry = *entry;
|
||||||
|
*entry = new_entry;
|
||||||
|
_entry_at_idx_update (vtable, self, entry_idx, &old_entry);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* delete */
|
/* delete */
|
||||||
_entry_at_idx_remove (vtable, self, entry_idx);
|
_entry_at_idx_remove (vtable, self, entry_idx);
|
||||||
|
|
@ -891,13 +892,15 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nm_default_route_manager_ip4_update_default_route (NMDefaultRouteManager *self, gpointer source)
|
nm_default_route_manager_ip4_update_default_route (NMDefaultRouteManager *self,
|
||||||
|
gpointer source)
|
||||||
{
|
{
|
||||||
_ipx_update_default_route (&vtable_ip4, self, source);
|
_ipx_update_default_route (&vtable_ip4, self, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nm_default_route_manager_ip6_update_default_route (NMDefaultRouteManager *self, gpointer source)
|
nm_default_route_manager_ip6_update_default_route (NMDefaultRouteManager *self,
|
||||||
|
gpointer source)
|
||||||
{
|
{
|
||||||
_ipx_update_default_route (&vtable_ip6, self, source);
|
_ipx_update_default_route (&vtable_ip6, self, source);
|
||||||
}
|
}
|
||||||
|
|
@ -1259,7 +1262,7 @@ static const VTableIP vtable_ip6 = {
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_resync_idle_now (NMDefaultRouteManager *self)
|
_resync_now (NMDefaultRouteManager *self)
|
||||||
{
|
{
|
||||||
gboolean has_v4_changes, has_v6_changes;
|
gboolean has_v4_changes, has_v6_changes;
|
||||||
gboolean changed = FALSE;
|
gboolean changed = FALSE;
|
||||||
|
|
@ -1274,7 +1277,7 @@ _resync_idle_now (NMDefaultRouteManager *self)
|
||||||
|
|
||||||
priv->resync.has_v4_changes = FALSE;
|
priv->resync.has_v4_changes = FALSE;
|
||||||
priv->resync.has_v6_changes = FALSE;
|
priv->resync.has_v6_changes = FALSE;
|
||||||
priv->resync.idle_handle = 0;
|
nm_clear_g_source (&priv->resync.idle_handle);
|
||||||
priv->resync.backoff_wait_time_ms =
|
priv->resync.backoff_wait_time_ms =
|
||||||
priv->resync.backoff_wait_time_ms == 0
|
priv->resync.backoff_wait_time_ms == 0
|
||||||
? 100
|
? 100
|
||||||
|
|
@ -1291,6 +1294,64 @@ _resync_idle_now (NMDefaultRouteManager *self)
|
||||||
_resync_idle_cancel (self);
|
_resync_idle_cancel (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_default_route_manager_resync:
|
||||||
|
* @self: the #NMDefaultRouteManager instance
|
||||||
|
* @af_family: the address family to resync, can be
|
||||||
|
* AF_INET, AF_INET6 or AF_UNSPEC to sync both.
|
||||||
|
*
|
||||||
|
* #NMDefaultRouteManager keeps an internal list of configured
|
||||||
|
* routes. Usually, it configures routes in the system only
|
||||||
|
* - when that internal list changes due to
|
||||||
|
* nm_default_route_manager_ip4_update_default_route() or
|
||||||
|
* nm_default_route_manager_ip6_update_default_route().
|
||||||
|
* - when platform notifies about changes, via _resync_idle_now().
|
||||||
|
* This forces a resync to update the internal bookkeeping
|
||||||
|
* with what is currently configured in the system, but also
|
||||||
|
* reconfigure the system with all non-assumed default routes.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if anything changed during resync.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
nm_default_route_manager_resync (NMDefaultRouteManager *self,
|
||||||
|
int af_family)
|
||||||
|
{
|
||||||
|
NMDefaultRouteManagerPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self), FALSE);
|
||||||
|
g_return_val_if_fail (NM_IN_SET (af_family, AF_INET, AF_INET6, AF_UNSPEC), FALSE);
|
||||||
|
|
||||||
|
priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
if (priv->disposed)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (af_family) {
|
||||||
|
case AF_INET:
|
||||||
|
priv->resync.has_v4_changes = TRUE;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
priv->resync.has_v6_changes = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
priv->resync.has_v4_changes = TRUE;
|
||||||
|
priv->resync.has_v6_changes = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _resync_now (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_resync_idle_now (NMDefaultRouteManager *self)
|
||||||
|
{
|
||||||
|
NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
priv->resync.idle_handle = 0;
|
||||||
|
_resync_now (self);
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1336,15 +1397,36 @@ _resync_idle_reschedule (NMDefaultRouteManager *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_platform_ipx_route_changed_cb (const VTableIP *vtable,
|
_platform_changed_cb (NMPlatform *platform,
|
||||||
NMDefaultRouteManager *self,
|
int obj_type_i,
|
||||||
const NMPlatformIPRoute *route)
|
int ifindex,
|
||||||
|
gpointer platform_object,
|
||||||
|
int change_type_i,
|
||||||
|
NMDefaultRouteManager *self)
|
||||||
{
|
{
|
||||||
NMDefaultRouteManagerPrivate *priv;
|
NMDefaultRouteManagerPrivate *priv;
|
||||||
|
const NMPObjectType obj_type = obj_type_i;
|
||||||
|
const VTableIP *vtable;
|
||||||
|
|
||||||
if (route && !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) {
|
switch (obj_type) {
|
||||||
/* we only care about address changes or changes of default route. */
|
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
||||||
return;
|
vtable = &vtable_ip4;
|
||||||
|
break;
|
||||||
|
case NMP_OBJECT_TYPE_IP6_ADDRESS:
|
||||||
|
vtable = &vtable_ip6;
|
||||||
|
break;
|
||||||
|
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
||||||
|
if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (platform_object))
|
||||||
|
return;
|
||||||
|
vtable = &vtable_ip4;
|
||||||
|
break;
|
||||||
|
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
||||||
|
if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (platform_object))
|
||||||
|
return;
|
||||||
|
vtable = &vtable_ip6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_return_if_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self);
|
priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self);
|
||||||
|
|
@ -1362,34 +1444,6 @@ _platform_ipx_route_changed_cb (const VTableIP *vtable,
|
||||||
_resync_idle_reschedule (self);
|
_resync_idle_reschedule (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_platform_changed_cb (NMPlatform *platform,
|
|
||||||
int obj_type_i,
|
|
||||||
int ifindex,
|
|
||||||
gpointer platform_object,
|
|
||||||
int change_type_i,
|
|
||||||
NMDefaultRouteManager *self)
|
|
||||||
{
|
|
||||||
const NMPObjectType obj_type = obj_type_i;
|
|
||||||
|
|
||||||
switch (obj_type) {
|
|
||||||
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
|
||||||
_platform_ipx_route_changed_cb (&vtable_ip4, self, NULL);
|
|
||||||
break;
|
|
||||||
case NMP_OBJECT_TYPE_IP6_ADDRESS:
|
|
||||||
_platform_ipx_route_changed_cb (&vtable_ip6, self, NULL);
|
|
||||||
break;
|
|
||||||
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
|
||||||
_platform_ipx_route_changed_cb (&vtable_ip4, self, (const NMPlatformIPRoute *) platform_object);
|
|
||||||
break;
|
|
||||||
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
|
||||||
_platform_ipx_route_changed_cb (&vtable_ip6, self, (const NMPlatformIPRoute *) platform_object);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_return_if_reached ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -61,4 +61,7 @@ NMIP6Config *nm_default_route_manager_ip6_get_best_config (NMDefaultRouteManager
|
||||||
NMDevice **out_device,
|
NMDevice **out_device,
|
||||||
NMVpnConnection **out_vpn);
|
NMVpnConnection **out_vpn);
|
||||||
|
|
||||||
|
gboolean nm_default_route_manager_resync (NMDefaultRouteManager *self,
|
||||||
|
int af_family);
|
||||||
|
|
||||||
#endif /* NM_DEFAULT_ROUTE_MANAGER_H */
|
#endif /* NM_DEFAULT_ROUTE_MANAGER_H */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue