default-route: don't return devices without active connection as best_config() or best_device()

Since 0c136c1e2, we also track the default route for devices
without active-connection (unmanaged). They must not be returned
as best_config() or as best_device(), because the caller don't
expect unmanaged devices here.

This also gets closer to the original behavior of get_best_device()
before merging default-route-manager in d4417e3460
where we also would ignore devices depending on the state.

This fixes an assertion when having an interface unmanaged
and activating it externally:

    #0  0x00007ffff6806187 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55
    #1  0x00007ffff6807dea in __GI_abort () at abort.c:89
    #2  0x00007ffff6c0aec5 in g_assertion_message (domain=domain@entry=0x5332d5 "NetworkManager", file=file@entry=0x539460 "nm-default-route-manager.c", line=line@entry=1056, func=func@entry=0x539920 <__FUNCTION__.28934> "_ipx_get_best_config", message=message@entry=0x8c9cb0 "assertion failed: (req)") at gtestutils.c:2356
    #3  0x00007ffff6c0af5a in g_assertion_message_expr (domain=domain@entry=0x5332d5 "NetworkManager", file=file@entry=0x539460 "nm-default-route-manager.c", line=line@entry=1056, func=func@entry=0x539920 <__FUNCTION__.28934> "_ipx_get_best_config", expr=expr@entry=0x53132f "req") at gtestutils.c:2371
    #4  0x000000000049a196 in _ipx_get_best_config (self=<optimized out>, ignore_never_default=ignore_never_default@entry=1, out_ip_iface=out_ip_iface@entry=0x7fffffffd310, out_ac=out_ac@entry=0x0, out_device=0x0, out_vpn=0x7fffffffd318, vtable=0x7a0a00 <vtable_ip4>, vtable=0x7a0a00 <vtable_ip4>) at nm-default-route-manager.c:1056
    #5  0x000000000049a3f6 in nm_default_route_manager_ip4_get_best_config (self=<optimized out>, ignore_never_default=ignore_never_default@entry=1, out_ip_iface=out_ip_iface@entry=0x7fffffffd310, out_ac=out_ac@entry=0x0, out_device=out_device@entry=0x0, out_vpn=out_vpn@entry=0x7fffffffd318) at nm-default-route-manager.c:1079
    #6  0x00000000004b7518 in update_ip4_dns (self=0x7ecac0 [NMPolicy], out_vpn=0x7fffffffd318, out_device=0x0, out_ac=0x0, out_ip_iface=0x7fffffffd310, ignore_never_default=1) at nm-policy.c:390
    #7  0x00000000004b7518 in update_ip4_dns (dns_mgr=0x8623a0 [NMDnsManager], policy=0x7ecac0 [NMPolicy]) at nm-policy.c:406
    #8  0x00000000004b99d5 in device_ip4_config_changed (device=0x8844b0 [NMDeviceEthernet], new_config=0x908aa0 [NMIP4Config], old_config=0x908aa0 [NMIP4Config], user_data=0x7ecac0) at nm-policy.c:1260
    #9  0x000000368f405d60 in ffi_call_unix64 () at /lib64/libffi.so.6
    #10 0x000000368f4057d1 in ffi_call () at /lib64/libffi.so.6
    #11 0x00007ffff6ee5b8c in g_cclosure_marshal_generic_va (closure=0x886a40, return_value=0x0, instance=0x8844b0, args_list=<optimized out>, marshal_data=0x0, n_params=2, param_types=0x87d3a0) at gclosure.c:1541
    #12 0x00007ffff6ee5144 in _g_closure_invoke_va (closure=closure@entry=0x886a40, return_value=return_value@entry=0x0, instance=instance@entry=0x8844b0, args=args@entry=0x7fffffffd810, n_params=<optimized out>, param_types=0x87d3a0) at gclosure.c:831
    #13 0x00007ffff6eff900 in g_signal_emit_valist (instance=0x8844b0, signal_id=<optimized out>, detail=0, var_args=var_args@entry=0x7fffffffd810) at gsignal.c:3201
    #14 0x00007ffff6f0014f in g_signal_emit (instance=instance@entry=0x8844b0, signal_id=<optimized out>, detail=detail@entry=0) at gsignal.c:3348
    #15 0x000000000044a1f4 in nm_device_set_ip4_config (self=self@entry=0x8844b0 [NMDeviceEthernet], new_config=new_config@entry=0x9089a0 [NMIP4Config], default_route_metric=default_route_metric@entry=100, commit=commit@entry=0, reason=reason@entry=0x0) at devices/nm-device.c:5866
    #16 0x000000000044a5af in ip4_config_merge_and_apply (self=self@entry=0x8844b0 [NMDeviceEthernet], config=config@entry=0x0, commit=commit@entry=0, out_reason=out_reason@entry=0x0) at devices/nm-device.c:3037
    #17 0x000000000044b4fd in update_ip_config (self=self@entry=0x8844b0 [NMDeviceEthernet], initial=initial@entry=0) at devices/nm-device.c:6617
    #18 0x000000000044bc39 in queued_ip_config_change (user_data=<optimized out>) at devices/nm-device.c:6688
    #19 0x00007ffff6be4e1b in g_main_context_dispatch (context=0x7ba3a0) at gmain.c:3122
    #20 0x00007ffff6be4e1b in g_main_context_dispatch (context=context@entry=0x7ba3a0) at gmain.c:3737
    #21 0x00007ffff6be51b0 in g_main_context_iterate (context=0x7ba3a0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3808
    #22 0x00007ffff6be54d2 in g_main_loop_run (loop=0x7ba460) at gmain.c:4002
    #23 0x000000000043291d in main (argc=1, argv=0x7fffffffdef8) at main.c:442

Fixes: da708059da
(cherry picked from commit aadef137b4)
This commit is contained in:
Thomas Haller 2015-01-26 15:03:48 +01:00
parent 5d00f4359e
commit 70d7d8a177

View file

@ -885,6 +885,7 @@ _ipx_get_best_device (const VTableIP *vtable, NMDefaultRouteManager *self, const
for (i = 0; i < entries->len; i++) {
Entry *entry = g_ptr_array_index (entries, i);
NMDeviceState state;
if (!NM_IS_DEVICE (entry->source.pointer))
continue;
@ -892,8 +893,22 @@ _ipx_get_best_device (const VTableIP *vtable, NMDefaultRouteManager *self, const
if (entry->never_default)
continue;
if (g_slist_find ((GSList *) devices, entry->source.device))
state = nm_device_get_state (entry->source.device);
if ( state <= NM_DEVICE_STATE_DISCONNECTED
|| state >= NM_DEVICE_STATE_DEACTIVATING) {
/* FIXME: we also track unmanaged devices with assumed default routes.
* Skip them, they are (currently) no candidates for best-device.
*
* Later we also want to properly assume connections for unmanaged devices.
*
* Also, we don't want to have DEACTIVATING devices returned as best_device(). */
continue;
}
if (g_slist_find ((GSList *) devices, entry->source.device)) {
g_return_val_if_fail (nm_device_get_act_request (entry->source.pointer), entry->source.pointer);
return entry->source.pointer;
}
}
return NULL;
}
@ -1043,10 +1058,24 @@ _ipx_get_best_config (const VTableIP *vtable,
} else {
NMDevice *device = entry->source.device;
NMActRequest *req;
NMDeviceState state;
if (entry->never_default)
continue;
state = nm_device_get_state (device);
if ( state <= NM_DEVICE_STATE_DISCONNECTED
|| state >= NM_DEVICE_STATE_DEACTIVATING) {
/* FIXME: the device has a default route, but we ignore it due to
* unexpected state. That happens for example for unmanaged devices.
*
* In the future, we want unmanaged devices also assume a connection
* if they are activated externally.
*
* Also, we don't want to have DEACTIVATING devices returned as best_config(). */
continue;
}
if (VTABLE_IS_IP4)
config_result = nm_device_get_ip4_config (device);
else