route-manager: merge branch 'th/route-full-sync'

Fix route manager not to delete externally added routes
but only routes that were previously added by route manager.

Also, add a test case and refactor the _exists() functions
to have them more useful.
This commit is contained in:
Thomas Haller 2015-07-14 13:41:00 +02:00
commit 5cc2eabe5d
19 changed files with 363 additions and 166 deletions

View file

@ -812,6 +812,38 @@ nmtst_platform_ip6_address_full (const char *address, const char *peer_address,
return addr;
}
inline static NMPlatformIP4Route *
nmtst_platform_ip4_route (const char *network, guint plen, const char *gateway)
{
static NMPlatformIP4Route route;
memset (&route, 0, sizeof (route));
route.network = nmtst_inet4_from_string (network);
route.plen = plen;
route.gateway = nmtst_inet4_from_string (gateway);
return &route;
}
inline static NMPlatformIP4Route *
nmtst_platform_ip4_route_full (const char *network, guint plen, const char *gateway,
int ifindex, NMIPConfigSource source,
guint metric, guint mss,
guint8 scope,
const char *pref_src)
{
NMPlatformIP4Route *route = nmtst_platform_ip4_route (network, plen, gateway);
route->ifindex = ifindex;
route->source = source;
route->metric = metric;
route->mss = mss;
route->scope_inv = nm_platform_route_scope_inv (scope);
route->pref_src = nmtst_inet4_from_string (pref_src);
return route;
}
inline static NMPlatformIP6Route *
nmtst_platform_ip6_route (const char *network, guint plen, const char *gateway)
{

View file

@ -351,6 +351,7 @@ static gboolean nm_device_set_ip4_config (NMDevice *self,
NMIP4Config *config,
guint32 default_route_metric,
gboolean commit,
gboolean routes_full_sync,
NMDeviceStateReason *reason);
static gboolean ip4_config_merge_and_apply (NMDevice *self,
NMIP4Config *config,
@ -360,6 +361,7 @@ static gboolean ip4_config_merge_and_apply (NMDevice *self,
static gboolean nm_device_set_ip6_config (NMDevice *self,
NMIP6Config *config,
gboolean commit,
gboolean routes_full_sync,
NMDeviceStateReason *reason);
static gboolean nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure);
@ -3248,6 +3250,7 @@ ip4_config_merge_and_apply (NMDevice *self,
const guint32 default_route_metric = nm_device_get_ip4_route_metric (self);
guint32 gateway;
gboolean connection_has_default_route, connection_is_never_default;
gboolean routes_full_sync;
/* Merge all the configs into the composite config */
if (config) {
@ -3312,6 +3315,10 @@ ip4_config_merge_and_apply (NMDevice *self,
priv->default_route.v4_has = FALSE;
priv->default_route.v4_is_assumed = TRUE;
routes_full_sync = commit
&& priv->default_route.v4_configure_first_time
&& !nm_device_uses_assumed_connection (self);
if (!commit) {
/* during a non-commit event, we always pickup whatever is configured. */
goto END_ADD_DEFAULT_ROUTE;
@ -3391,7 +3398,7 @@ END_ADD_DEFAULT_ROUTE:
NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, composite);
}
success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, out_reason);
success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, routes_full_sync, out_reason);
g_object_unref (composite);
return success;
}
@ -3864,6 +3871,7 @@ ip6_config_merge_and_apply (NMDevice *self,
gboolean has_direct_route;
const struct in6_addr *gateway;
gboolean connection_has_default_route, connection_is_never_default;
gboolean routes_full_sync;
/* If no config was passed in, create a new one */
composite = nm_ip6_config_new (nm_device_get_ip_ifindex (self));
@ -3926,6 +3934,10 @@ ip6_config_merge_and_apply (NMDevice *self,
priv->default_route.v6_has = FALSE;
priv->default_route.v6_is_assumed = TRUE;
routes_full_sync = commit
&& priv->default_route.v6_configure_first_time
&& !nm_device_uses_assumed_connection (self);
if (!commit) {
/* during a non-commit event, we always pickup whatever is configured. */
goto END_ADD_DEFAULT_ROUTE;
@ -4008,7 +4020,7 @@ END_ADD_DEFAULT_ROUTE:
NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, composite);
}
success = nm_device_set_ip6_config (self, composite, commit, out_reason);
success = nm_device_set_ip6_config (self, composite, commit, routes_full_sync, out_reason);
g_object_unref (composite);
return success;
}
@ -6317,6 +6329,7 @@ nm_device_set_ip4_config (NMDevice *self,
NMIP4Config *new_config,
guint32 default_route_metric,
gboolean commit,
gboolean routes_full_sync,
NMDeviceStateReason *reason)
{
NMDevicePrivate *priv;
@ -6351,6 +6364,7 @@ nm_device_set_ip4_config (NMDevice *self,
* FIXME: this is wrong in case where "assumed" means "take-over-seamlessly". In this
* case, we should manage the device route, for example on new DHCP lease. */
success = nm_ip4_config_commit (new_config, ip_ifindex,
routes_full_sync,
assumed ? (gint64) -1 : (gint64) default_route_metric);
if (!success)
reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
@ -6456,6 +6470,7 @@ static gboolean
nm_device_set_ip6_config (NMDevice *self,
NMIP6Config *new_config,
gboolean commit,
gboolean routes_full_sync,
NMDeviceStateReason *reason)
{
NMDevicePrivate *priv;
@ -6483,7 +6498,9 @@ nm_device_set_ip6_config (NMDevice *self,
/* Always commit to nm-platform to update lifetimes */
if (commit && new_config) {
nm_device_ipv6_set_mtu (self, priv->ip6_mtu);
success = nm_ip6_config_commit (new_config, ip_ifindex);
success = nm_ip6_config_commit (new_config,
ip_ifindex,
routes_full_sync);
if (!success)
reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
}
@ -7937,8 +7954,8 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type)
/* Clean up IP configs; this does not actually deconfigure the
* interface; the caller must flush routes and addresses explicitly.
*/
nm_device_set_ip4_config (self, NULL, 0, TRUE, &ignored);
nm_device_set_ip6_config (self, NULL, TRUE, &ignored);
nm_device_set_ip4_config (self, NULL, 0, TRUE, TRUE, &ignored);
nm_device_set_ip6_config (self, NULL, TRUE, TRUE, &ignored);
g_clear_object (&priv->con_ip4_config);
g_clear_object (&priv->dev_ip4_config);
g_clear_object (&priv->ext_ip4_config);

View file

@ -104,7 +104,7 @@ dhcp4_state_changed (NMDhcpClient *client,
nm_ip4_config_subtract (existing, last_config);
nm_ip4_config_merge (existing, ip4_config);
if (!nm_ip4_config_commit (existing, ifindex, global_opt.priority_v4))
if (!nm_ip4_config_commit (existing, ifindex, TRUE, global_opt.priority_v4))
nm_log_warn (LOGD_DHCP4, "(%s): failed to apply DHCPv4 config", global_opt.ifname);
if (last_config)
@ -241,7 +241,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
nm_ip6_config_subtract (existing, last_config);
nm_ip6_config_merge (existing, ip6_config);
if (!nm_ip6_config_commit (existing, ifindex))
if (!nm_ip6_config_commit (existing, ifindex, TRUE))
nm_log_warn (LOGD_IP6, "(%s): failed to apply IPv6 config", global_opt.ifname);
if (last_config)

View file

@ -290,7 +290,7 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf)
}
gboolean
nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gint64 default_route_metric)
nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_full_sync, gint64 default_route_metric)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
int i;
@ -359,7 +359,7 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gint64 default_rou
nm_route_manager_ip4_route_register_device_route_purge_list (nm_route_manager_get (), device_route_purge_list);
success = nm_route_manager_ip4_route_sync (nm_route_manager_get (), ifindex, routes, default_route_metric < 0);
success = nm_route_manager_ip4_route_sync (nm_route_manager_get (), ifindex, routes, default_route_metric < 0, routes_full_sync);
g_array_unref (routes);
if (!success)
return FALSE;

View file

@ -71,7 +71,7 @@ const char * nm_ip4_config_get_dbus_path (const NMIP4Config *config);
/* Integration with nm-platform and nm-setting */
NMIP4Config *nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf);
gboolean nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gint64 default_route_metric);
gboolean nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_full_sync, gint64 default_route_metric);
void nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, guint32 default_route_metric);
NMSetting *nm_ip4_config_create_setting (const NMIP4Config *config);

View file

@ -406,7 +406,7 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co
}
gboolean
nm_ip6_config_commit (const NMIP6Config *config, int ifindex)
nm_ip6_config_commit (const NMIP6Config *config, int ifindex, gboolean routes_full_sync)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
int i;
@ -437,7 +437,7 @@ nm_ip6_config_commit (const NMIP6Config *config, int ifindex)
g_array_append_vals (routes, route, 1);
}
success = nm_route_manager_ip6_route_sync (nm_route_manager_get (), ifindex, routes, TRUE);
success = nm_route_manager_ip6_route_sync (nm_route_manager_get (), ifindex, routes, TRUE, routes_full_sync);
g_array_unref (routes);
}

View file

@ -71,7 +71,7 @@ const char * nm_ip6_config_get_dbus_path (const NMIP6Config *config);
/* Integration with nm-platform and nm-setting */
NMIP6Config *nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6ConfigPrivacy use_temporary);
gboolean nm_ip6_config_commit (const NMIP6Config *config, int ifindex);
gboolean nm_ip6_config_commit (const NMIP6Config *config, int ifindex, gboolean routes_full_sync);
void nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, guint32 default_route_metric);
NMSetting *nm_ip6_config_create_setting (const NMIP6Config *config);

View file

@ -445,7 +445,7 @@ _sort_indexes_cmp (guint *a, guint *b)
/*********************************************************************************************/
static gboolean
_vx_route_sync (const VTableIP *vtable, NMRouteManager *self, int ifindex, const GArray *known_routes, gboolean ignore_kernel_routes)
_vx_route_sync (const VTableIP *vtable, NMRouteManager *self, int ifindex, const GArray *known_routes, gboolean ignore_kernel_routes, gboolean full_sync)
{
NMRouteManagerPrivate *priv = NM_ROUTE_MANAGER_GET_PRIVATE (self);
GArray *plat_routes;
@ -484,7 +484,7 @@ _vx_route_sync (const VTableIP *vtable, NMRouteManager *self, int ifindex, const
ifindex, i, vtable->vt->route_to_string (VTABLE_ROUTE_INDEX (vtable, known_routes, i)));
}
for (i = 0; i < ipx_routes->index->len; i++)
_LOGT (vtable->vt->addr_family, "%3d: STATE: has #%u - %s (%lld)",
_LOGT (vtable->vt->addr_family, "%3d: STATE: has #%u - %s (%lld)",
ifindex, i,
vtable->vt->route_to_string (ipx_routes->index->entries[i]),
(long long) g_array_index (ipx_routes->effective_metrics, gint64, i));
@ -526,7 +526,7 @@ _vx_route_sync (const VTableIP *vtable, NMRouteManager *self, int ifindex, const
cur_ipx_route->rx.ifindex = ifindex;
cur_ipx_route->rx.metric = vtable->vt->metric_normalize (cur_ipx_route->rx.metric);
ipx_routes_changed = TRUE;
_LOGT (vtable->vt->addr_family, "%3d: STATE: update #%u - %s", ifindex, i_ipx_routes, vtable->vt->route_to_string (cur_ipx_route));
_LOGT (vtable->vt->addr_family, "%3d: STATE: update #%u - %s", ifindex, i_ipx_routes, vtable->vt->route_to_string (cur_ipx_route));
}
} else if (cur_known_route) {
g_assert (!cur_ipx_route || route_id_cmp_result > 0);
@ -543,13 +543,60 @@ _vx_route_sync (const VTableIP *vtable, NMRouteManager *self, int ifindex, const
cur_known_route = _get_next_known_route (vtable, known_routes_idx, FALSE, &i_known_routes);
}
if (!full_sync && to_delete_indexes) {
/***************************************************************************
* Delete routes in platform, that we are about to remove from @ipx_routes
*
* When doing a non-full_sync, we delete routes from platform that were previously
* known by route-manager, and are now deleted.
***************************************************************************/
/* iterate over @to_delete_indexes and @plat_routes.
* @to_delete_indexes contains the indexes (relative to ipx_routes->index) of items
* we are about to delete. */
cur_plat_route = _get_next_plat_route (plat_routes_idx, TRUE, &i_plat_routes);
for (i = 0; i < to_delete_indexes->len; i++) {
int route_dest_cmp_result = 0;
i_ipx_routes = g_array_index (to_delete_indexes, guint, i);
cur_ipx_route = ipx_routes->index->entries[i_ipx_routes];
p_effective_metric = &effective_metrics[i_ipx_routes];
nm_assert (cur_ipx_route->rx.ifindex == ifindex);
if (*p_effective_metric == -1)
continue;
/* skip over @plat_routes that are ordered before our @cur_ipx_route. */
while ( cur_plat_route
&& (route_dest_cmp_result = vtable->route_dest_cmp (cur_plat_route, cur_ipx_route)) <= 0) {
if ( route_dest_cmp_result == 0
&& cur_plat_route->rx.metric >= *p_effective_metric)
break;
cur_plat_route = _get_next_plat_route (plat_routes_idx, FALSE, &i_plat_routes);
}
if (!cur_plat_route) {
/* no more platform routes. Break the loop. */
break;
}
if ( route_dest_cmp_result == 0
&& cur_plat_route->rx.metric == *p_effective_metric) {
/* we are about to delete cur_ipx_route and we have a matching route
* in platform. Delete it. */
_LOGT (vtable->vt->addr_family, "%3d: platform rt-rm #%u - %s", ifindex, i_plat_routes, vtable->vt->route_to_string (cur_plat_route));
vtable->vt->route_delete (priv->platform, ifindex, cur_plat_route);
}
}
}
/* Update @ipx_routes with the just learned changes. */
if (to_delete_indexes || to_add_routes) {
if (to_delete_indexes) {
for (i = 0; i < to_delete_indexes->len; i++) {
guint idx = g_array_index (to_delete_indexes, guint, i);
_LOGT (vtable->vt->addr_family, "%3d: STATE: delete #%u - %s", ifindex, idx, vtable->vt->route_to_string (ipx_routes->index->entries[idx]));
_LOGT (vtable->vt->addr_family, "%3d: STATE: delete #%u - %s", ifindex, idx, vtable->vt->route_to_string (ipx_routes->index->entries[idx]));
g_array_index (to_delete_indexes, guint, i) = _route_index_reverse_idx (vtable, ipx_routes->index, idx, ipx_routes->entries);
}
g_array_sort (to_delete_indexes, (GCompareFunc) _sort_indexes_cmp);
@ -573,7 +620,7 @@ _vx_route_sync (const VTableIP *vtable, NMRouteManager *self, int ifindex, const
g_array_index (ipx_routes->effective_metrics_reverse, gint64, j++) = -1;
_LOGT (vtable->vt->addr_family, "%3d: STATE: added #%u - %s", ifindex, ipx_routes->entries->len - 1, vtable->vt->route_to_string (ipx_route));
_LOGT (vtable->vt->addr_family, "%3d: STATE: added #%u - %s", ifindex, ipx_routes->entries->len - 1, vtable->vt->route_to_string (ipx_route));
}
g_ptr_array_unref (to_add_routes);
}
@ -658,49 +705,54 @@ _vx_route_sync (const VTableIP *vtable, NMRouteManager *self, int ifindex, const
break;
}
next:
_LOGT (vtable->vt->addr_family, "%3d: new metric #%u - %s (%lld)",
_LOGT (vtable->vt->addr_family, "%3d: new metric #%u - %s (%lld)",
ifindex, i_ipx_routes,
vtable->vt->route_to_string (cur_ipx_route),
(long long) *p_effective_metric);
}
}
/***************************************************************************
* Delete routes in platform, that no longer exist in @ipx_routes
***************************************************************************/
if (full_sync) {
/***************************************************************************
* Delete all routes in platform, that no longer exist in @ipx_routes
*
* Different from the delete action above, we delete every unknown route on
* the interface.
***************************************************************************/
/* iterate over @plat_routes and @ipx_routes */
cur_plat_route = _get_next_plat_route (plat_routes_idx, TRUE, &i_plat_routes);
cur_ipx_route = _get_next_ipx_route (ipx_routes->index, TRUE, &i_ipx_routes, ifindex);
if (cur_ipx_route)
p_effective_metric = &effective_metrics[i_ipx_routes];
while (cur_plat_route) {
int route_dest_cmp_result = 0;
/* iterate over @plat_routes and @ipx_routes */
cur_plat_route = _get_next_plat_route (plat_routes_idx, TRUE, &i_plat_routes);
cur_ipx_route = _get_next_ipx_route (ipx_routes->index, TRUE, &i_ipx_routes, ifindex);
if (cur_ipx_route)
p_effective_metric = &effective_metrics[i_ipx_routes];
while (cur_plat_route) {
int route_dest_cmp_result = 0;
g_assert (cur_plat_route->rx.ifindex == ifindex);
g_assert (cur_plat_route->rx.ifindex == ifindex);
_LOGT (vtable->vt->addr_family, "%3d: platform rt #%u - %s", ifindex, i_plat_routes, vtable->vt->route_to_string (cur_plat_route));
_LOGT (vtable->vt->addr_family, "%3d: platform rt #%u - %s", ifindex, i_plat_routes, vtable->vt->route_to_string (cur_plat_route));
/* skip over @cur_ipx_route that are ordered before @cur_plat_route */
while ( cur_ipx_route
&& ((route_dest_cmp_result = vtable->route_dest_cmp (cur_ipx_route, cur_plat_route)) <= 0)) {
if ( route_dest_cmp_result == 0
&& *p_effective_metric != -1
&& *p_effective_metric >= cur_plat_route->rx.metric) {
break;
/* skip over @cur_ipx_route that are ordered before @cur_plat_route */
while ( cur_ipx_route
&& ((route_dest_cmp_result = vtable->route_dest_cmp (cur_ipx_route, cur_plat_route)) <= 0)) {
if ( route_dest_cmp_result == 0
&& *p_effective_metric != -1
&& *p_effective_metric >= cur_plat_route->rx.metric) {
break;
}
cur_ipx_route = _get_next_ipx_route (ipx_routes->index, FALSE, &i_ipx_routes, ifindex);
if (cur_ipx_route)
p_effective_metric = &effective_metrics[i_ipx_routes];
}
cur_ipx_route = _get_next_ipx_route (ipx_routes->index, FALSE, &i_ipx_routes, ifindex);
if (cur_ipx_route)
p_effective_metric = &effective_metrics[i_ipx_routes];
/* if @cur_ipx_route is not equal to @plat_route, the route must be deleted. */
if ( !cur_ipx_route
|| route_dest_cmp_result != 0
|| *p_effective_metric != cur_plat_route->rx.metric)
vtable->vt->route_delete (priv->platform, ifindex, cur_plat_route);
cur_plat_route = _get_next_plat_route (plat_routes_idx, FALSE, &i_plat_routes);
}
/* if @cur_ipx_route is not equal to @plat_route, the route must be deleted. */
if ( !cur_ipx_route
|| route_dest_cmp_result != 0
|| *p_effective_metric != cur_plat_route->rx.metric)
vtable->vt->route_delete (priv->platform, ifindex, cur_plat_route);
cur_plat_route = _get_next_plat_route (plat_routes_idx, FALSE, &i_plat_routes);
}
/***************************************************************************
@ -796,7 +848,7 @@ next:
* we need to know whether a route is shadowed by another route, and that
* requires to look at @ipx_routes. */
for (; cur_ipx_route; cur_ipx_route = _get_next_ipx_route (ipx_routes->index, FALSE, &i_ipx_routes, ifindex)) {
int route_id_dest_result = -1;
int route_dest_cmp_result = -1;
if ( (i_type == 0 && !VTABLE_IS_DEVICE_ROUTE (vtable, cur_ipx_route))
|| (i_type == 1 && VTABLE_IS_DEVICE_ROUTE (vtable, cur_ipx_route))) {
@ -814,8 +866,8 @@ next:
/* skip over @plat_routes that are ordered before our @cur_ipx_route. */
while ( cur_plat_route
&& (route_id_dest_result = vtable->route_dest_cmp (cur_plat_route, cur_ipx_route)) <= 0) {
if ( route_id_dest_result == 0
&& (route_dest_cmp_result = vtable->route_dest_cmp (cur_plat_route, cur_ipx_route)) <= 0) {
if ( route_dest_cmp_result == 0
&& cur_plat_route->rx.metric >= *p_effective_metric)
break;
cur_plat_route = _get_next_plat_route (plat_routes_idx, FALSE, &i_plat_routes);
@ -824,7 +876,7 @@ next:
/* only add the route if we don't have an identical route in @plat_routes,
* i.e. if @cur_plat_route is different from @cur_ipx_route. */
if ( !cur_plat_route
|| route_id_dest_result != 0
|| route_dest_cmp_result != 0
|| !_route_equals_ignoring_ifindex (vtable, cur_plat_route, cur_ipx_route, *p_effective_metric)) {
if (!vtable->vt->route_add (priv->platform, ifindex, cur_ipx_route, *p_effective_metric)) {
@ -855,6 +907,9 @@ next:
* @ifindex: Interface index
* @known_routes: List of routes
* @ignore_kernel_routes: if %TRUE, ignore kernel routes.
* @full_sync: whether to do a full sync and delete routes
* that are configured on the interface but not currently
* tracked by route-manager.
*
* A convenience function to synchronize routes for a specific interface
* with the least possible disturbance. It simply removes routes that are
@ -865,9 +920,9 @@ next:
* Returns: %TRUE on success.
*/
gboolean
nm_route_manager_ip4_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes, gboolean ignore_kernel_routes)
nm_route_manager_ip4_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes, gboolean ignore_kernel_routes, gboolean full_sync)
{
return _vx_route_sync (&vtable_v4, self, ifindex, known_routes, ignore_kernel_routes);
return _vx_route_sync (&vtable_v4, self, ifindex, known_routes, ignore_kernel_routes, full_sync);
}
/**
@ -875,6 +930,9 @@ nm_route_manager_ip4_route_sync (NMRouteManager *self, int ifindex, const GArray
* @ifindex: Interface index
* @known_routes: List of routes
* @ignore_kernel_routes: if %TRUE, ignore kernel routes.
* @full_sync: whether to do a full sync and delete routes
* that are configured on the interface but not currently
* tracked by route-manager.
*
* A convenience function to synchronize routes for a specific interface
* with the least possible disturbance. It simply removes routes that are
@ -885,16 +943,16 @@ nm_route_manager_ip4_route_sync (NMRouteManager *self, int ifindex, const GArray
* Returns: %TRUE on success.
*/
gboolean
nm_route_manager_ip6_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes, gboolean ignore_kernel_routes)
nm_route_manager_ip6_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes, gboolean ignore_kernel_routes, gboolean full_sync)
{
return _vx_route_sync (&vtable_v6, self, ifindex, known_routes, ignore_kernel_routes);
return _vx_route_sync (&vtable_v6, self, ifindex, known_routes, ignore_kernel_routes, full_sync);
}
gboolean
nm_route_manager_route_flush (NMRouteManager *self, int ifindex)
{
return nm_route_manager_ip4_route_sync (self, ifindex, NULL, FALSE)
&& nm_route_manager_ip6_route_sync (self, ifindex, NULL, FALSE);
return nm_route_manager_ip4_route_sync (self, ifindex, NULL, FALSE, TRUE)
&& nm_route_manager_ip6_route_sync (self, ifindex, NULL, FALSE, TRUE);
}
/*********************************************************************************************/

View file

@ -42,8 +42,8 @@ typedef struct {
GType nm_route_manager_get_type (void);
gboolean nm_route_manager_ip4_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes, gboolean ignore_kernel_routes);
gboolean nm_route_manager_ip6_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes, gboolean ignore_kernel_routes);
gboolean nm_route_manager_ip4_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes, gboolean ignore_kernel_routes, gboolean full_sync);
gboolean nm_route_manager_ip6_route_sync (NMRouteManager *self, int ifindex, const GArray *known_routes, gboolean ignore_kernel_routes, gboolean full_sync);
gboolean nm_route_manager_route_flush (NMRouteManager *self, int ifindex);
void nm_route_manager_ip4_route_register_device_route_purge_list (NMRouteManager *self, GArray *device_route_purge_list);

View file

@ -992,8 +992,8 @@ ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int
return TRUE;
}
static gboolean
ip4_address_exists (NMPlatform *platform, int ifindex, in_addr_t addr, int plen)
static const NMPlatformIP4Address *
ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, int plen)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
int i;
@ -1002,14 +1002,14 @@ ip4_address_exists (NMPlatform *platform, int ifindex, in_addr_t addr, int plen)
NMPlatformIP4Address *address = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i);
if (address->ifindex == ifindex && address->plen == plen && address->address == addr)
return TRUE;
return address;
}
return FALSE;
return NULL;
}
static gboolean
ip6_address_exists (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen)
static const NMPlatformIP6Address *
ip6_address_get (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
int i;
@ -1019,10 +1019,10 @@ ip6_address_exists (NMPlatform *platform, int ifindex, struct in6_addr addr, int
if (address->ifindex == ifindex && address->plen == plen &&
IN6_ARE_ADDR_EQUAL (&address->address, &addr))
return TRUE;
return address;
}
return FALSE;
return NULL;
}
/******************************************************************/
@ -1271,7 +1271,7 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source,
return TRUE;
}
static NMPlatformIP4Route *
static const NMPlatformIP4Route *
ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
@ -1290,7 +1290,7 @@ ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, int plen, g
return NULL;
}
static NMPlatformIP6Route *
static const NMPlatformIP6Route *
ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric)
{
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
@ -1311,18 +1311,6 @@ ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, int p
return NULL;
}
static gboolean
ip4_route_exists (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric)
{
return !!ip4_route_get (platform, ifindex, network, plen, metric);
}
static gboolean
ip6_route_exists (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric)
{
return !!ip6_route_get (platform, ifindex, network, plen, metric);
}
/******************************************************************/
static void
@ -1453,21 +1441,21 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
platform_class->mesh_set_channel = mesh_set_channel;
platform_class->mesh_set_ssid = mesh_set_ssid;
platform_class->ip4_address_get = ip4_address_get;
platform_class->ip6_address_get = ip6_address_get;
platform_class->ip4_address_get_all = ip4_address_get_all;
platform_class->ip6_address_get_all = ip6_address_get_all;
platform_class->ip4_address_add = ip4_address_add;
platform_class->ip6_address_add = ip6_address_add;
platform_class->ip4_address_delete = ip4_address_delete;
platform_class->ip6_address_delete = ip6_address_delete;
platform_class->ip4_address_exists = ip4_address_exists;
platform_class->ip6_address_exists = ip6_address_exists;
platform_class->ip4_route_get = ip4_route_get;
platform_class->ip6_route_get = ip6_route_get;
platform_class->ip4_route_get_all = ip4_route_get_all;
platform_class->ip6_route_get_all = ip6_route_get_all;
platform_class->ip4_route_add = ip4_route_add;
platform_class->ip6_route_add = ip6_route_add;
platform_class->ip4_route_delete = ip4_route_delete;
platform_class->ip6_route_delete = ip6_route_delete;
platform_class->ip4_route_exists = ip4_route_exists;
platform_class->ip6_route_exists = ip6_route_exists;
}

View file

@ -4163,22 +4163,30 @@ ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int
return do_delete_object (platform, &obj_needle, NULL);
}
static gboolean
ip4_address_exists (NMPlatform *platform, int ifindex, in_addr_t addr, int plen)
static const NMPlatformIP4Address *
ip4_address_get (NMPlatform *platform, int ifindex, in_addr_t addr, int plen)
{
NMPObject obj_needle;
const NMPObject *obj;
nmp_object_stackinit_id_ip4_address (&obj_needle, ifindex, addr, plen);
return nmp_object_is_visible (nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle));
obj = nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle);
if (nmp_object_is_visible (obj))
return &obj->ip4_address;
return NULL;
}
static gboolean
ip6_address_exists (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen)
static const NMPlatformIP6Address *
ip6_address_get (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen)
{
NMPObject obj_needle;
const NMPObject *obj;
nmp_object_stackinit_id_ip6_address (&obj_needle, ifindex, &addr, plen);
return nmp_object_is_visible (nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle));
obj = nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle);
if (nmp_object_is_visible (obj))
return &obj->ip6_address;
return NULL;
}
/******************************************************************/
@ -4461,24 +4469,32 @@ ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, in
return do_delete_object (platform, &obj_needle, nlo);
}
static gboolean
ip4_route_exists (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric)
static const NMPlatformIP4Route *
ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric)
{
NMPObject obj_needle;
const NMPObject *obj;
nmp_object_stackinit_id_ip4_route (&obj_needle, ifindex, network, plen, metric);
return nmp_object_is_visible (nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle));
obj = nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle);
if (nmp_object_is_visible (obj))
return &obj->ip4_route;
return NULL;
}
static gboolean
ip6_route_exists (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric)
static const NMPlatformIP6Route *
ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric)
{
NMPObject obj_needle;
const NMPObject *obj;
metric = nm_utils_ip6_route_metric_normalize (metric);
nmp_object_stackinit_id_ip6_route (&obj_needle, ifindex, &network, plen, metric);
return nmp_object_is_visible (nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle));
obj = nmp_cache_lookup_obj (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, &obj_needle);
if (nmp_object_is_visible (obj))
return &obj->ip6_route;
return NULL;
}
/******************************************************************/
@ -4985,23 +5001,23 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->mesh_set_channel = mesh_set_channel;
platform_class->mesh_set_ssid = mesh_set_ssid;
platform_class->ip4_address_get = ip4_address_get;
platform_class->ip6_address_get = ip6_address_get;
platform_class->ip4_address_get_all = ip4_address_get_all;
platform_class->ip6_address_get_all = ip6_address_get_all;
platform_class->ip4_address_add = ip4_address_add;
platform_class->ip6_address_add = ip6_address_add;
platform_class->ip4_address_delete = ip4_address_delete;
platform_class->ip6_address_delete = ip6_address_delete;
platform_class->ip4_address_exists = ip4_address_exists;
platform_class->ip6_address_exists = ip6_address_exists;
platform_class->ip4_route_get = ip4_route_get;
platform_class->ip6_route_get = ip6_route_get;
platform_class->ip4_route_get_all = ip4_route_get_all;
platform_class->ip6_route_get_all = ip6_route_get_all;
platform_class->ip4_route_add = ip4_route_add;
platform_class->ip6_route_add = ip6_route_add;
platform_class->ip4_route_delete = ip4_route_delete;
platform_class->ip6_route_delete = ip6_route_delete;
platform_class->ip4_route_exists = ip4_route_exists;
platform_class->ip6_route_exists = ip6_route_exists;
platform_class->check_support_kernel_extended_ifa_flags = check_support_kernel_extended_ifa_flags;
platform_class->check_support_user_ipv6ll = check_support_user_ipv6ll;

View file

@ -1971,26 +1971,24 @@ nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr a
return klass->ip6_address_delete (self, ifindex, address, plen);
}
gboolean
nm_platform_ip4_address_exists (NMPlatform *self, int ifindex, in_addr_t address, int plen)
const NMPlatformIP4Address *
nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, int plen)
{
_CHECK_SELF (self, klass, FALSE);
g_return_val_if_fail (plen > 0, FALSE);
g_return_val_if_fail (klass->ip4_address_exists, FALSE);
return klass->ip4_address_exists (self, ifindex, address, plen);
return klass->ip4_address_get (self, ifindex, address, plen);
}
gboolean
nm_platform_ip6_address_exists (NMPlatform *self, int ifindex, struct in6_addr address, int plen)
const NMPlatformIP6Address *
nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address, int plen)
{
_CHECK_SELF (self, klass, FALSE);
g_return_val_if_fail (plen > 0, FALSE);
g_return_val_if_fail (klass->ip6_address_exists, FALSE);
return klass->ip6_address_exists (self, ifindex, address, plen);
return klass->ip6_address_get (self, ifindex, address, plen);
}
static gboolean
@ -2272,24 +2270,20 @@ nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr net
return klass->ip6_route_delete (self, ifindex, network, plen, metric);
}
gboolean
nm_platform_ip4_route_exists (NMPlatform *self, int ifindex, in_addr_t network, int plen, guint32 metric)
const NMPlatformIP4Route *
nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, int plen, guint32 metric)
{
_CHECK_SELF (self, klass, FALSE);
g_return_val_if_fail (klass->ip4_route_exists, FALSE);
return klass->ip4_route_exists (self ,ifindex, network, plen, metric);
return klass->ip4_route_get (self ,ifindex, network, plen, metric);
}
gboolean
nm_platform_ip6_route_exists (NMPlatform *self, int ifindex, struct in6_addr network, int plen, guint32 metric)
const NMPlatformIP6Route *
nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, int plen, guint32 metric)
{
_CHECK_SELF (self, klass, FALSE);
g_return_val_if_fail (klass->ip6_route_exists, FALSE);
return klass->ip6_route_exists (self, ifindex, network, plen, metric);
return klass->ip6_route_get (self, ifindex, network, plen, metric);
}
/******************************************************************/

View file

@ -518,8 +518,8 @@ typedef struct {
guint32 lifetime, guint32 preferred_lft, guint flags);
gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, int plen, in_addr_t peer_address);
gboolean (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, int plen);
gboolean (*ip4_address_exists) (NMPlatform *, int ifindex, in_addr_t address, int plen);
gboolean (*ip6_address_exists) (NMPlatform *, int ifindex, struct in6_addr address, int plen);
const NMPlatformIP4Address *(*ip4_address_get) (NMPlatform *, int ifindex, in_addr_t address, int plen);
const NMPlatformIP6Address *(*ip6_address_get) (NMPlatform *, int ifindex, struct in6_addr address, int plen);
GArray * (*ip4_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteFlags flags);
GArray * (*ip6_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteFlags flags);
@ -531,8 +531,8 @@ typedef struct {
guint32 metric, guint32 mss);
gboolean (*ip4_route_delete) (NMPlatform *, int ifindex, in_addr_t network, int plen, guint32 metric);
gboolean (*ip6_route_delete) (NMPlatform *, int ifindex, struct in6_addr network, int plen, guint32 metric);
gboolean (*ip4_route_exists) (NMPlatform *, int ifindex, in_addr_t network, int plen, guint32 metric);
gboolean (*ip6_route_exists) (NMPlatform *, int ifindex, struct in6_addr network, int plen, guint32 metric);
const NMPlatformIP4Route *(*ip4_route_get) (NMPlatform *, int ifindex, in_addr_t network, int plen, guint32 metric);
const NMPlatformIP6Route *(*ip6_route_get) (NMPlatform *, int ifindex, struct in6_addr network, int plen, guint32 metric);
gboolean (*check_support_kernel_extended_ifa_flags) (NMPlatform *);
gboolean (*check_support_user_ipv6ll) (NMPlatform *);
@ -692,6 +692,8 @@ guint32 nm_platform_mesh_get_channel (NMPlatform *self, int ifindex);
gboolean nm_platform_mesh_set_channel (NMPlatform *self, int ifindex, guint32 channel);
gboolean nm_platform_mesh_set_ssid (NMPlatform *self, int ifindex, const guint8 *ssid, gsize len);
const NMPlatformIP4Address *nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, int plen);
const NMPlatformIP6Address *nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address, int plen);
GArray *nm_platform_ip4_address_get_all (NMPlatform *self, int ifindex);
GArray *nm_platform_ip6_address_get_all (NMPlatform *self, int ifindex);
gboolean nm_platform_ip4_address_add (NMPlatform *self, int ifindex,
@ -703,12 +705,12 @@ gboolean nm_platform_ip6_address_add (NMPlatform *self, int ifindex,
guint32 lifetime, guint32 preferred_lft, guint flags);
gboolean nm_platform_ip4_address_delete (NMPlatform *self, int ifindex, in_addr_t address, int plen, in_addr_t peer_address);
gboolean nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr address, int plen);
gboolean nm_platform_ip4_address_exists (NMPlatform *self, int ifindex, in_addr_t address, int plen);
gboolean nm_platform_ip6_address_exists (NMPlatform *self, int ifindex, struct in6_addr address, int plen);
gboolean nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArray *known_addresses, GPtrArray **out_added_addresses);
gboolean nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known_addresses, gboolean keep_link_local);
gboolean nm_platform_address_flush (NMPlatform *self, int ifindex);
const NMPlatformIP4Route *nm_platform_ip4_route_get (NMPlatform *self, int ifindex, in_addr_t network, int plen, guint32 metric);
const NMPlatformIP6Route *nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr network, int plen, guint32 metric);
GArray *nm_platform_ip4_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRouteFlags flags);
GArray *nm_platform_ip6_route_get_all (NMPlatform *self, int ifindex, NMPlatformGetRouteFlags flags);
gboolean nm_platform_ip4_route_add (NMPlatform *self, int ifindex, NMIPConfigSource source,
@ -719,8 +721,6 @@ gboolean nm_platform_ip6_route_add (NMPlatform *self, int ifindex, NMIPConfigSou
guint32 metric, guint32 mss);
gboolean nm_platform_ip4_route_delete (NMPlatform *self, int ifindex, in_addr_t network, int plen, guint32 metric);
gboolean nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6_addr network, int plen, guint32 metric);
gboolean nm_platform_ip4_route_exists (NMPlatform *self, int ifindex, in_addr_t network, int plen, guint32 metric);
gboolean nm_platform_ip6_route_exists (NMPlatform *self, int ifindex, struct in6_addr network, int plen, guint32 metric);
const char *nm_platform_link_to_string (const NMPlatformLink *link);
const char *nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address);

View file

@ -615,7 +615,7 @@ do_ip6_address_add (char **argv)
v##_t address; \
int plen; \
if (ifindex && parse_##v##_address (*argv++, &address, &plen)) { \
gboolean value = nm_platform_##v##_address_##cmdname (NM_PLATFORM_GET, ifindex, address, plen, ##__VA_ARGS__); \
gboolean value = !!nm_platform_##v##_address_##cmdname (NM_PLATFORM_GET, ifindex, address, plen, ##__VA_ARGS__); \
if (print) { \
print_boolean (value); \
return TRUE; \
@ -628,7 +628,7 @@ do_ip6_address_add (char **argv)
#define ADDR_CMD_PRINT(cmdname) ADDR_CMD_FULL (ip4, cmdname, TRUE) ADDR_CMD_FULL (ip6, cmdname, TRUE)
ADDR_CMD (delete)
ADDR_CMD_PRINT (exists)
ADDR_CMD_PRINT (get)
static gboolean
do_ip4_route_get_all (char **argv)
@ -738,7 +738,7 @@ do_ip6_route_delete (char **argv)
}
static gboolean
do_ip4_route_exists (char **argv)
do_ip4_route_get (char **argv)
{
int ifindex = parse_ifindex (*argv++);
in_addr_t network;
@ -747,12 +747,12 @@ do_ip4_route_exists (char **argv)
parse_ip4_address (*argv++, &network, &plen);
metric = strtol (*argv++, NULL, 10);
print_boolean (nm_platform_ip4_route_exists (NM_PLATFORM_GET, ifindex, network, plen, metric));
print_boolean (!!nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
return TRUE;
}
static gboolean
do_ip6_route_exists (char **argv)
do_ip6_route_get (char **argv)
{
int ifindex = parse_ifindex (*argv++);
struct in6_addr network;
@ -761,7 +761,7 @@ do_ip6_route_exists (char **argv)
parse_ip6_address (*argv++, &network, &plen);
metric = strtol (*argv++, NULL, 10);
print_boolean (nm_platform_ip6_route_exists (NM_PLATFORM_GET, ifindex, network, plen, metric));
print_boolean (!!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
return TRUE;
}
@ -838,9 +838,9 @@ static const command_t commands[] = {
"<ifname/ifindex> <address>/<plen>" },
{ "ip6-address-delete", "delete IPv6 address", do_ip6_address_delete, 2,
"<ifname/ifindex> <address>/<plen>" },
{ "ip4-address-exists", "check for existence of IPv4 address", do_ip4_address_exists, 2,
{ "ip4-address-exists", "check for existence of IPv4 address", do_ip4_address_get, 2,
"<ifname/ifindex> <address>/<plen>" },
{ "ip6-address-exists", "check for existence of IPv6 address", do_ip6_address_exists, 2,
{ "ip6-address-exists", "check for existence of IPv6 address", do_ip6_address_get, 2,
"<ifname/ifindex> <address>/<plen>" },
{ "ip4-route-get-all", "print all IPv4 routes", do_ip4_route_get_all, 1, "<ifname/ifindex>" },
{ "ip6-route-get-all", "print all IPv6 routes", do_ip6_route_get_all, 1, "<ifname/ifindex>" },
@ -852,9 +852,9 @@ static const command_t commands[] = {
"<ifname/ifindex> <network>/<plen> <metric>" },
{ "ip6-route-delete", "delete IPv6 route", do_ip6_route_delete, 3,
"<ifname/ifindex> <network>/<plen> <metric>" },
{ "ip4-route-exists", "check for existence of IPv4 route", do_ip4_route_exists, 3,
{ "ip4-route-exists", "check for existence of IPv4 route", do_ip4_route_get, 3,
"<ifname/ifindex> <network>/<plen> <metric>" },
{ "ip6-route-exists", "check for existence of IPv6 route", do_ip6_route_exists, 3,
{ "ip6-route-exists", "check for existence of IPv6 route", do_ip6_route_get, 3,
"<ifname/ifindex> <network>/<plen> <metric>" },
{ NULL, NULL, NULL, 0, NULL },
};

View file

@ -64,9 +64,9 @@ test_ip4_address (void)
inet_pton (AF_INET, IP4_ADDRESS, &addr);
/* Add address */
g_assert (!nm_platform_ip4_address_exists (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
g_assert (nm_platform_ip4_address_exists (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
accept_signal (address_added);
/* Add address again (aka update) */
@ -85,7 +85,7 @@ test_ip4_address (void)
/* Remove address */
g_assert (nm_platform_ip4_address_delete (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, 0));
g_assert (!nm_platform_ip4_address_exists (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
accept_signal (address_removed);
/* Remove address again */
@ -113,9 +113,9 @@ test_ip6_address (void)
inet_pton (AF_INET6, IP6_ADDRESS, &addr);
/* Add address */
g_assert (!nm_platform_ip6_address_exists (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr, in6addr_any, IP6_PLEN, lifetime, preferred, flags));
g_assert (nm_platform_ip6_address_exists (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
accept_signal (address_added);
/* Add address again (aka update) */
@ -134,7 +134,7 @@ test_ip6_address (void)
/* Remove address */
g_assert (nm_platform_ip6_address_delete (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (!nm_platform_ip6_address_exists (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
accept_signal (address_removed);
/* Remove address again */
@ -167,20 +167,20 @@ test_ip4_address_external (void)
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred);
wait_signal (address_added);
g_assert (nm_platform_ip4_address_exists (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME);
wait_signal (address_removed);
g_assert (!nm_platform_ip4_address_exists (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
/* Add/delete conflict */
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred);
g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr, 0, IP4_PLEN, lifetime, preferred, NULL));
g_assert (nm_platform_ip4_address_exists (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
accept_signal (address_added);
/*run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME);
g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN, 0));
g_assert (!nm_platform_ip4_address_exists (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN));
accept_signal (address_removed);*/
free_signal (address_added);
@ -204,20 +204,20 @@ test_ip6_address_external (void)
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
IP6_ADDRESS, IP6_PLEN, DEVICE_NAME, lifetime, preferred);
wait_signal (address_added);
g_assert (nm_platform_ip6_address_exists (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
run_command ("ip address delete %s/%d dev %s", IP6_ADDRESS, IP6_PLEN, DEVICE_NAME);
wait_signal (address_removed);
g_assert (!nm_platform_ip6_address_exists (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
/* Add/delete conflict */
run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d",
IP6_ADDRESS, IP6_PLEN, DEVICE_NAME, lifetime, preferred);
g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr, in6addr_any, IP6_PLEN, lifetime, preferred, flags));
g_assert (nm_platform_ip6_address_exists (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
accept_signal (address_added);
/*run_command ("ip address delete %s/%d dev %s", IP6_ADDRESS, IP6_PLEN, DEVICE_NAME);
g_assert (nm_platform_ip6_address_delete (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (!nm_platform_ip6_address_exists (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr, IP6_PLEN));
wait_signal (address_removed);*/
free_signal (address_added);

View file

@ -244,7 +244,7 @@ _assert_ip4_route_exists (const char *file, guint line, const char *func, gboole
ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, ifname);
g_assert (ifindex > 0);
if (!nm_platform_ip4_route_exists (NM_PLATFORM_GET, ifindex, network, plen, metric) != !exists) {
if (!nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric) != !exists) {
g_error ("[%s:%u] %s(): The ip4 route %s/%d metric %u %s, but platform thinks %s",
file, line, func,
nm_utils_inet4_ntop (network, NULL), plen, metric,

View file

@ -222,9 +222,9 @@ test_ip6_route (void)
accept_signal (route_added);
/* Add route */
g_assert (!nm_platform_ip6_route_exists (NM_PLATFORM_GET, ifindex, network, plen, metric));
g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, metric, mss));
g_assert (nm_platform_ip6_route_exists (NM_PLATFORM_GET, ifindex, network, plen, metric));
g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
accept_signal (route_added);
/* Add route again */
@ -232,9 +232,9 @@ test_ip6_route (void)
accept_signals (route_changed, 0, 1);
/* Add default route */
g_assert (!nm_platform_ip6_route_exists (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric));
g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric));
g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, metric, mss));
g_assert (nm_platform_ip6_route_exists (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric));
g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric));
accept_signal (route_added);
/* Add default route again */
@ -271,7 +271,7 @@ test_ip6_route (void)
/* Remove route */
g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
g_assert (!nm_platform_ip6_route_exists (NM_PLATFORM_GET, ifindex, network, plen, metric));
g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
accept_signal (route_removed);
/* Remove route again */

View file

@ -36,6 +36,8 @@ typedef struct {
int ifindex0, ifindex1;
} test_fixture;
/*****************************************************************************/
static void
setup_dev0_ip4 (int ifindex, guint mss_of_first_route, guint32 metric_of_second_route)
{
@ -61,7 +63,7 @@ setup_dev0_ip4 (int ifindex, guint mss_of_first_route, guint32 metric_of_second_
route.mss = 0;
g_array_append_val (routes, route);
nm_route_manager_ip4_route_sync (nm_route_manager_get (), ifindex, routes, TRUE);
nm_route_manager_ip4_route_sync (nm_route_manager_get (), ifindex, routes, TRUE, TRUE);
g_array_free (routes, TRUE);
}
@ -107,7 +109,7 @@ setup_dev1_ip4 (int ifindex)
route.metric = 22;
g_array_append_val (routes, route);
nm_route_manager_ip4_route_sync (nm_route_manager_get (), ifindex, routes, TRUE);
nm_route_manager_ip4_route_sync (nm_route_manager_get (), ifindex, routes, TRUE, TRUE);
g_array_free (routes, TRUE);
}
@ -134,7 +136,7 @@ update_dev0_ip4 (int ifindex)
route.metric = 21;
g_array_append_val (routes, route);
nm_route_manager_ip4_route_sync (nm_route_manager_get (), ifindex, routes, TRUE);
nm_route_manager_ip4_route_sync (nm_route_manager_get (), ifindex, routes, TRUE, TRUE);
g_array_free (routes, TRUE);
}
@ -409,7 +411,7 @@ setup_dev0_ip6 (int ifindex)
0);
g_array_append_val (routes, *route);
nm_route_manager_ip6_route_sync (nm_route_manager_get (), ifindex, routes, TRUE);
nm_route_manager_ip6_route_sync (nm_route_manager_get (), ifindex, routes, TRUE, TRUE);
g_array_free (routes, TRUE);
}
@ -466,7 +468,7 @@ setup_dev1_ip6 (int ifindex)
0);
g_array_append_val (routes, *route);
nm_route_manager_ip6_route_sync (nm_route_manager_get (), ifindex, routes, TRUE);
nm_route_manager_ip6_route_sync (nm_route_manager_get (), ifindex, routes, TRUE, TRUE);
g_array_free (routes, TRUE);
}
@ -513,7 +515,7 @@ update_dev0_ip6 (int ifindex)
0);
g_array_append_val (routes, *route);
nm_route_manager_ip6_route_sync (nm_route_manager_get (), ifindex, routes, TRUE);
nm_route_manager_ip6_route_sync (nm_route_manager_get (), ifindex, routes, TRUE, TRUE);
g_array_free (routes, TRUE);
}
@ -779,6 +781,89 @@ test_ip6 (test_fixture *fixture, gconstpointer user_data)
g_array_free (routes, TRUE);
}
/*****************************************************************************/
static void
_assert_route_check (const NMPlatformVTableRoute *vtable, gboolean has, const NMPlatformIPXRoute *route)
{
const NMPlatformIPXRoute *r;
g_assert (route);
if (vtable->is_ip4)
r = (const NMPlatformIPXRoute *) nm_platform_ip4_route_get (NM_PLATFORM_GET, route->rx.ifindex, route->r4.network, route->rx.plen, route->rx.metric);
else
r = (const NMPlatformIPXRoute *) nm_platform_ip6_route_get (NM_PLATFORM_GET, route->rx.ifindex, route->r6.network, route->rx.plen, route->rx.metric);
if (!has) {
g_assert (!r);
} else {
if (!r || vtable->route_cmp (route, r) != 0)
g_error ("Invalid route. Expect %s, has %s",
nmtst_static_1024_01 (vtable->route_to_string (route)),
nmtst_static_1024_02 (vtable->route_to_string (r)));
g_assert (r);
}
}
static void
test_ip4_full_sync (test_fixture *fixture, gconstpointer user_data)
{
const NMPlatformVTableRoute *vtable = &nm_platform_vtable_route_v4;
gs_unref_array GArray *routes = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Route));
NMPlatformIP4Route r01, r02, r03;
nm_log_dbg (LOGD_CORE, "TEST start test_ip4_full_sync(): start");
r01 = *nmtst_platform_ip4_route_full ("12.3.4.0", 24, NULL,
fixture->ifindex0, NM_IP_CONFIG_SOURCE_USER,
100, 0, RT_SCOPE_LINK, NULL);
r02 = *nmtst_platform_ip4_route_full ("13.4.5.6", 32, "12.3.4.1",
fixture->ifindex0, NM_IP_CONFIG_SOURCE_USER,
100, 0, RT_SCOPE_UNIVERSE, NULL);
r03 = *nmtst_platform_ip4_route_full ("14.5.6.7", 32, "12.3.4.1",
fixture->ifindex0, NM_IP_CONFIG_SOURCE_USER,
110, 0, RT_SCOPE_UNIVERSE, NULL);
g_array_set_size (routes, 2);
g_array_index (routes, NMPlatformIP4Route, 0) = r01;
g_array_index (routes, NMPlatformIP4Route, 1) = r02;
nm_route_manager_ip4_route_sync (nm_route_manager_get (), fixture->ifindex0, routes, TRUE, TRUE);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r01);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r02);
_assert_route_check (vtable, FALSE, (const NMPlatformIPXRoute *) &r03);
vtable->route_add (NM_PLATFORM_GET, 0, (const NMPlatformIPXRoute *) &r03, -1);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r01);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r02);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r03);
nm_route_manager_ip4_route_sync (nm_route_manager_get (), fixture->ifindex0, routes, TRUE, FALSE);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r01);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r02);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r03);
g_array_set_size (routes, 1);
nm_route_manager_ip4_route_sync (nm_route_manager_get (), fixture->ifindex0, routes, TRUE, FALSE);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r01);
_assert_route_check (vtable, FALSE, (const NMPlatformIPXRoute *) &r02);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r03);
nm_route_manager_ip4_route_sync (nm_route_manager_get (), fixture->ifindex0, routes, TRUE, TRUE);
_assert_route_check (vtable, TRUE, (const NMPlatformIPXRoute *) &r01);
_assert_route_check (vtable, FALSE, (const NMPlatformIPXRoute *) &r02);
_assert_route_check (vtable, FALSE, (const NMPlatformIPXRoute *) &r03);
nm_log_dbg (LOGD_CORE, "TEST test_ip4_full_sync(): done");
}
/*****************************************************************************/
static void
fixture_setup (test_fixture *fixture, gconstpointer user_data)
{
@ -816,6 +901,8 @@ fixture_teardown (test_fixture *fixture, gconstpointer user_data)
nm_platform_link_delete (NM_PLATFORM_GET, fixture->ifindex1);
}
/*****************************************************************************/
void
init_tests (int *argc, char ***argv)
{
@ -827,4 +914,6 @@ setup_tests (void)
{
g_test_add ("/route-manager/ip4", test_fixture, NULL, fixture_setup, test_ip4, fixture_teardown);
g_test_add ("/route-manager/ip6", test_fixture, NULL, fixture_setup, test_ip6, fixture_teardown);
g_test_add ("/route-manager/ip4-full-sync", test_fixture, NULL, fixture_setup, test_ip4_full_sync, fixture_teardown);
}

View file

@ -961,12 +961,15 @@ nm_vpn_connection_apply_config (NMVpnConnection *connection)
if (priv->ip4_config) {
if (!nm_ip4_config_commit (priv->ip4_config, priv->ip_ifindex,
TRUE,
nm_vpn_connection_get_ip4_route_metric (connection)))
return FALSE;
}
if (priv->ip6_config) {
if (!nm_ip6_config_commit (priv->ip6_config, priv->ip_ifindex))
if (!nm_ip6_config_commit (priv->ip6_config,
priv->ip_ifindex,
TRUE))
return FALSE;
}
}