default-route-manager: use NMPlatformVTableRoute

(cherry picked from commit 110200d5d4)
This commit is contained in:
Thomas Haller 2015-03-25 11:49:38 +01:00
parent 1ff6f6c304
commit 7916dc0f4a

View file

@ -141,22 +141,16 @@ typedef struct {
} Entry;
typedef struct {
int addr_family;
const NMPlatformVTableRoute *vt;
GPtrArray *(*get_entries) (NMDefaultRouteManagerPrivate *priv);
const char *(*platform_route_to_string) (const NMPlatformIPRoute *route);
GArray *(*platform_route_get_all) (int ifindex, NMPlatformGetRouteMode mode);
gboolean (*platform_route_delete_default) (int ifindex, guint32 metric);
guint32 (*route_metric_normalize) (guint32 metric);
} VTableIP;
static const VTableIP vtable_ip4, vtable_ip6;
#define VTABLE_IS_IP4 (vtable->addr_family == AF_INET)
static NMPlatformIPRoute *
_vt_route_index (const VTableIP *vtable, GArray *routes, guint index)
{
if (VTABLE_IS_IP4)
if (vtable->vt->is_ip4)
return (NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP4Route, index);
else
return (NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP6Route, index);
@ -170,7 +164,7 @@ _vt_routes_has_entry (const VTableIP *vtable, GArray *routes, const Entry *entry
route.rx.metric = entry->effective_metric;
if (VTABLE_IS_IP4) {
if (vtable->vt->is_ip4) {
for (i = 0; i < routes->len; i++) {
NMPlatformIP4Route *r = &g_array_index (routes, NMPlatformIP4Route, i);
@ -260,7 +254,7 @@ _platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, g
if (!entry)
return FALSE;
if (VTABLE_IS_IP4) {
if (vtable->vt->is_ip4) {
success = nm_platform_ip4_route_add (entry->route.rx.ifindex,
entry->route.rx.source,
0,
@ -279,8 +273,8 @@ _platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, g
entry->route.rx.mss);
}
if (!success) {
_LOGW (vtable->addr_family, "failed to add default route %s with effective metric %u",
vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric);
_LOGW (vtable->vt->addr_family, "failed to add default route %s with effective metric %u",
vtable->vt->route_to_string (&entry->route), (guint) entry->effective_metric);
}
return TRUE;
}
@ -295,7 +289,7 @@ _platform_route_sync_flush (const VTableIP *vtable, NMDefaultRouteManager *self,
gboolean changed = FALSE;
/* prune all other default routes from this device. */
routes = vtable->platform_route_get_all (0, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT);
routes = vtable->vt->route_get_all (0, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT);
for (i = 0; i < routes->len; i++) {
const NMPlatformIPRoute *route;
@ -327,7 +321,7 @@ _platform_route_sync_flush (const VTableIP *vtable, NMDefaultRouteManager *self,
*/
if ( !entry
&& (has_ifindex_synced || ifindex_to_flush == route->ifindex)) {
vtable->platform_route_delete_default (route->ifindex, route->metric);
vtable->vt->route_delete_default (route->ifindex, route->metric);
changed = TRUE;
}
}
@ -411,7 +405,7 @@ _get_assumed_interface_metrics (const VTableIP *vtable, NMDefaultRouteManager *s
}
if (!ifindex_has_synced_entry)
g_hash_table_add (result, GUINT_TO_POINTER (vtable->route_metric_normalize (route->metric)));
g_hash_table_add (result, GUINT_TO_POINTER (vtable->vt->metric_normalize (route->metric)));
}
return result;
@ -447,7 +441,7 @@ _resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *c
priv->resync.guard++;
if (!external_change) {
if (VTABLE_IS_IP4)
if (vtable->vt->is_ip4)
priv->resync.has_v4_changes = FALSE;
else
priv->resync.has_v6_changes = FALSE;
@ -457,7 +451,7 @@ _resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *c
entries = vtable->get_entries (priv);
routes = vtable->platform_route_get_all (0, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT);
routes = vtable->vt->route_get_all (0, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT);
assumed_metrics = _get_assumed_interface_metrics (vtable, self, routes);
@ -527,24 +521,24 @@ _resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *c
* or none. Hence, we only have to remember what is going to change. */
g_array_append_val (changed_metrics, expected_metric);
if (old_entry) {
_LOGD (vtable->addr_family, LOG_ENTRY_FMT": update %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry),
vtable->platform_route_to_string (&entry->route.rx), (guint) old_entry->effective_metric,
_LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": update %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry),
vtable->vt->route_to_string (&entry->route), (guint) old_entry->effective_metric,
(guint) expected_metric);
} else {
_LOGD (vtable->addr_family, LOG_ENTRY_FMT": add %s (%u)", LOG_ENTRY_ARGS (i, entry),
vtable->platform_route_to_string (&entry->route.rx), (guint) expected_metric);
_LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": add %s (%u)", LOG_ENTRY_ARGS (i, entry),
vtable->vt->route_to_string (&entry->route), (guint) expected_metric);
}
} else if (entry->effective_metric != expected_metric) {
g_array_append_val (changed_metrics, entry->effective_metric);
g_array_append_val (changed_metrics, expected_metric);
_LOGD (vtable->addr_family, LOG_ENTRY_FMT": resync metric %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry),
vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric,
_LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": resync metric %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry),
vtable->vt->route_to_string (&entry->route), (guint) entry->effective_metric,
(guint) expected_metric);
} else {
if (!_vt_routes_has_entry (vtable, routes, entry)) {
g_array_append_val (changed_metrics, entry->effective_metric);
_LOGD (vtable->addr_family, LOG_ENTRY_FMT": readd route %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry),
vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric,
_LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": readd route %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry),
vtable->vt->route_to_string (&entry->route), (guint) entry->effective_metric,
(guint) entry->effective_metric);
}
}
@ -608,10 +602,10 @@ _entry_at_idx_update (const VTableIP *vtable, NMDefaultRouteManager *self, guint
if (!entry->synced && !entry->never_default)
entry->effective_metric = entry->route.rx.metric;
_LOGD (vtable->addr_family, LOG_ENTRY_FMT": %s %s",
_LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": %s %s",
LOG_ENTRY_ARGS (entry_idx, entry),
old_entry ? "update" : "add",
vtable->platform_route_to_string (&entry->route.rx));
vtable->vt->route_to_string (&entry->route));
g_ptr_array_sort_with_data (entries, _sort_entries_cmp, NULL);
@ -631,8 +625,8 @@ _entry_at_idx_remove (const VTableIP *vtable, NMDefaultRouteManager *self, guint
entry = g_ptr_array_index (entries, entry_idx);
_LOGD (vtable->addr_family, LOG_ENTRY_FMT": remove %s (%u)", LOG_ENTRY_ARGS (entry_idx, entry),
vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric);
_LOGD (vtable->vt->addr_family, LOG_ENTRY_FMT": remove %s (%u)", LOG_ENTRY_ARGS (entry_idx, entry),
vtable->vt->route_to_string (&entry->route), (guint) entry->effective_metric);
/* Remove the entry from the list (but don't free it yet) */
g_ptr_array_index (entries, entry_idx) = NULL;
@ -692,7 +686,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
if ( entry
&& entry->route.rx.ifindex != ip_ifindex) {
/* Strange... the ifindex changed... Remove the device and start again. */
_LOGD (vtable->addr_family, "ifindex of "LOG_ENTRY_FMT" changed: %d -> %d",
_LOGD (vtable->vt->addr_family, "ifindex of "LOG_ENTRY_FMT" changed: %d -> %d",
LOG_ENTRY_ARGS (entry_idx, entry),
entry->route.rx.ifindex, ip_ifindex);
@ -709,7 +703,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
if (device) {
gboolean is_assumed;
if (VTABLE_IS_IP4)
if (vtable->vt->is_ip4)
default_route = (const NMPlatformIPRoute *) nm_device_get_ip4_default_route (device, &is_assumed);
else
default_route = (const NMPlatformIPRoute *) nm_device_get_ip6_default_route (device, &is_assumed);
@ -737,7 +731,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
&& nm_vpn_connection_get_vpn_state (vpn) == NM_VPN_CONNECTION_STATE_ACTIVATED) {
memset (&rt, 0, sizeof (rt));
if (VTABLE_IS_IP4) {
if (vtable->vt->is_ip4) {
NMIP4Config *vpn_config;
vpn_config = nm_vpn_connection_get_ip4_config (vpn);
@ -779,13 +773,13 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
entry = g_slice_new0 (Entry);
entry->source.object = g_object_ref (source);
if (VTABLE_IS_IP4)
if (vtable->vt->is_ip4)
entry->route.r4 = *((const NMPlatformIP4Route *) default_route);
else
entry->route.r6 = *((const NMPlatformIP6Route *) default_route);
/* only use normalized metrics */
entry->route.rx.metric = vtable->route_metric_normalize (entry->route.rx.metric);
entry->route.rx.metric = vtable->vt->metric_normalize (entry->route.rx.metric);
entry->route.rx.ifindex = ip_ifindex;
entry->never_default = never_default;
entry->effective_metric = entry->route.rx.metric;
@ -798,12 +792,12 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self,
Entry old_entry, new_entry;
new_entry = *entry;
if (VTABLE_IS_IP4)
if (vtable->vt->is_ip4)
new_entry.route.r4 = *((const NMPlatformIP4Route *) default_route);
else
new_entry.route.r6 = *((const NMPlatformIP6Route *) default_route);
/* only use normalized metrics */
new_entry.route.rx.metric = vtable->route_metric_normalize (new_entry.route.rx.metric);
new_entry.route.rx.metric = vtable->vt->metric_normalize (new_entry.route.rx.metric);
new_entry.route.rx.ifindex = ip_ifindex;
new_entry.never_default = never_default;
new_entry.synced = synced;
@ -843,14 +837,14 @@ _ipx_connection_has_default_route (const VTableIP *vtable, NMDefaultRouteManager
g_return_val_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
if (VTABLE_IS_IP4)
if (vtable->vt->is_ip4)
s_ip = nm_connection_get_setting_ip4_config (connection);
else
s_ip = nm_connection_get_setting_ip6_config (connection);
if (!s_ip || nm_setting_ip_config_get_never_default (s_ip))
return FALSE;
if (VTABLE_IS_IP4) {
if (vtable->vt->is_ip4) {
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
if ( !method
|| !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)
@ -980,7 +974,7 @@ _ipx_get_best_activating_device (const VTableIP *vtable, NMDefaultRouteManager *
prio = nm_device_get_ip4_route_metric (device);
}
prio = vtable->route_metric_normalize (prio);
prio = vtable->vt->metric_normalize (prio);
if ( !best_device
|| prio < best_prio
@ -1062,7 +1056,7 @@ _ipx_get_best_config (const VTableIP *vtable,
if (entry->never_default && !ignore_never_default)
continue;
if (VTABLE_IS_IP4)
if (vtable->vt->is_ip4)
config_result = nm_vpn_connection_get_ip4_config (vpn);
else
config_result = nm_vpn_connection_get_ip6_config (vpn);
@ -1095,7 +1089,7 @@ _ipx_get_best_config (const VTableIP *vtable,
continue;
}
if (VTABLE_IS_IP4)
if (vtable->vt->is_ip4)
config_result = nm_device_get_ip4_config (device);
else
config_result = nm_device_get_ip6_config (device);
@ -1164,40 +1158,14 @@ _v6_get_entries (NMDefaultRouteManagerPrivate *priv)
return priv->entries_ip6;
}
static gboolean
_v4_platform_route_delete_default (int ifindex, guint32 metric)
{
return nm_platform_ip4_route_delete (ifindex, 0, 0, metric);
}
static gboolean
_v6_platform_route_delete_default (int ifindex, guint32 metric)
{
return nm_platform_ip6_route_delete (ifindex, in6addr_any, 0, metric);
}
static guint32
_v4_route_metric_normalize (guint32 metric)
{
return metric;
}
static const VTableIP vtable_ip4 = {
.addr_family = AF_INET,
.vt = &nm_platform_vtable_route_v4,
.get_entries = _v4_get_entries,
.platform_route_to_string = (const char *(*)(const NMPlatformIPRoute *)) nm_platform_ip4_route_to_string,
.platform_route_get_all = nm_platform_ip4_route_get_all,
.platform_route_delete_default = _v4_platform_route_delete_default,
.route_metric_normalize = _v4_route_metric_normalize,
};
static const VTableIP vtable_ip6 = {
.addr_family = AF_INET6,
.vt = &nm_platform_vtable_route_v6,
.get_entries = _v6_get_entries,
.platform_route_to_string = (const char *(*)(const NMPlatformIPRoute *)) nm_platform_ip6_route_to_string,
.platform_route_get_all = nm_platform_ip6_route_get_all,
.platform_route_delete_default = _v6_platform_route_delete_default,
.route_metric_normalize = nm_utils_ip6_route_metric_normalize,
};
/***********************************************************************************/
@ -1308,7 +1276,7 @@ _platform_ipx_route_changed_cb (const VTableIP *vtable,
return;
}
if (VTABLE_IS_IP4)
if (vtable->vt->is_ip4)
priv->resync.has_v4_changes = TRUE;
else
priv->resync.has_v6_changes = TRUE;