Backtrace:
NetworkManager[10972]: <debug> [1435142179.593334] [platform/nm-platform.c:2962] log_ip4_route(): signal: route 4 removed: 0.0.0.0/0 via 192.168.100.1 dev 85 metric 300 mss 0 src user scope global
NetworkManager[10972]: <debug> [1435142179.593421] [platform/nm-platform.c:2944] log_link(): signal: link removed: 85: bond0 <DOWN;broadcast,multicast,master> mtu 1500 arp 1 bond* init addr 7A:AB:BE:0D:19:3D driver bond
NetworkManager[10972]: <debug> [1435142179.593446] [nm-manager.c:779] remove_device(): (bond0): removing device (allow_unmanage 1, managed 1)
NetworkManager[10972]: <debug> [1435142179.596995] [devices/nm-device.c:7232] nm_device_set_unmanaged(): [0x5555559d2a40] (bond0): now unmanaged
NetworkManager[10972]: (devices/nm-device.c:8040):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
#0 0x00007ffff4a538c3 in g_logv () at /lib64/libglib-2.0.so.0
#1 0x00007ffff4a53a3f in g_log () at /lib64/libglib-2.0.so.0
#2 0x00007ffff4a53d56 in g_warn_message () at /lib64/libglib-2.0.so.0
#3 0x00005555555b9dca in _set_state_full (self=0x5555559d2a40, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_REMOVED, quitting=0) at devices/nm-device.c:8040
#4 0x0000555555626d7b in remove_device (manager=0x5555559631e0, device=0x5555559d2a40, quitting=0, allow_unmanage=<optimized out>) at nm-manager.c:801
#5 0x00007ffff28b7dac in ffi_call_unix64 () at /lib64/libffi.so.6
#6 0x00007ffff28b76d5 in ffi_call () at /lib64/libffi.so.6
#7 0x00007ffff4d4a628 in g_cclosure_marshal_generic () at /lib64/libgobject-2.0.so.0
#8 0x00007ffff4d49de8 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#9 0x00007ffff4d5b70d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
#10 0x00007ffff4d63471 in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
#11 0x00007ffff4d63c78 in g_signal_emit_by_name () at /lib64/libgobject-2.0.so.0
#12 0x00005555555ce4ea in do_emit_signal (platform=platform@entry=0x55555594c8b0, obj=0x555555a74c50, cache_op=NMP_CACHE_OPS_REMOVED, was_visible=<optimized out>, reason=reason@entry=
NM_PLATFORM_REASON_INTERNAL) at platform/nm-linux-platform.c:1425
#13 0x00005555555ce826 in cache_prune_candidates_prune (platform=platform@entry=0x55555594c8b0) at platform/nm-linux-platform.c:1704
#14 0x00005555555d32d3 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=85, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=0)
at platform/nm-linux-platform.c:1951
#15 0x00005555555d356b in delayed_action_handle_all (ifindex=85, platform=0x55555594c8b0) at platform/nm-linux-platform.c:1491
#16 0x00005555555d356b in delayed_action_handle_all (platform=0x55555594c8b0) at platform/nm-linux-platform.c:1573
#17 0x00005555555d356b in delayed_action_handle_all (platform=platform@entry=0x55555594c8b0, read_netlink=read_netlink@entry=0) at platform/nm-linux-platform.c:1588
#18 0x00005555555d32e2 in do_request_link (platform=platform@entry=0x55555594c8b0, ifindex=ifindex@entry=7, name=name@entry=0x0, handle_delayed_action=handle_delayed_action@entry=1)
at platform/nm-linux-platform.c:1954
#19 0x00005555555d5177 in do_change_link (platform=platform@entry=0x55555594c8b0, nlo=nlo@entry=0x55555597f0f0, complete_from_cache=complete_from_cache@entry=1) at platform/nm-linux-platform.c:2753
#20 0x00005555555d56b4 in link_enslave (platform=0x55555594c8b0, master=0, slave=7) at platform/nm-linux-platform.c:3141
#21 0x00005555555976de in release_slave (device=0x5555559d2a40, slave=0x5555559c6be0, configure=<optimized out>) at devices/nm-device-bond.c:437
#22 0x00005555555b7bc3 in nm_device_release_one_slave (self=self@entry=0x5555559d2a40, slave=0x5555559c6be0, configure=configure@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:1049
#23 0x00005555555b7f0e in nm_device_master_release_slaves (self=self@entry=0x5555559d2a40) at devices/nm-device.c:1781
#24 0x00005555555b9592 in nm_device_cleanup (self=0x5555559d2a40, reason=<optimized out>, deconfigure=1) at devices/nm-device.c:7752
#25 0x00005555555ba161 in _set_state_full (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, quitting=quitting@entry=0) at devices/nm-device.c:8128
#26 0x00005555555bb297 in nm_device_state_changed (self=self@entry=0x5555559d2a40, state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
at devices/nm-device.c:8319
#27 0x00005555555bd9a5 in queued_set_state (user_data=<optimized out>) at devices/nm-device.c:8343
#28 0x00007ffff4a4c79a in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#29 0x00007ffff4a4cae8 in g_main_context_iterate.isra.24 () at /lib64/libglib-2.0.so.0
#30 0x00007ffff4a4cdba in g_main_loop_run () at /lib64/libglib-2.0.so.0
#31 0x000055555559556f in main (argc=1, argv=0x7fffffffdb88) at main.c:518
(cherry picked from commit d48902e605)
Without that we can remove addresses from con-ip6-config due to external
changes *before* it is applied and thus manual IPv6 addresses are not applied
together with ipv6.method=auto.
Testcase:
$ nmcli con add type ether con-name AAA ifname eth0 autoconnect no
$ nmcli con mod AAA ipv4.addresses 1.1.1.1/24 ipv6.addresses 99::99/64
$ nmcli con up AAA
Fixes:Beaker:NetworkManager_Test37_run_once_new_connection
Fixes:Beaker:NetworkManager_Test84_ipv6_addresses_no_when_static_switch_asked
https://bugzilla.gnome.org/show_bug.cgi?id=751430
(cherry picked from commit 0a00eb67dd)
Compare against the interface of the candidate master connection, not the slave
connection itself.
Fixes: 179d56c73c
(cherry picked from commit 33f954e251)
The merge of lr/udev-unmanaged-fd731014 made all devices wait until
udev found them, but that makes these three device types fail activate
when created by NM itself.
Since their availability depended on IFF_UP, they could not be
activated (eg, 'nmcli con up team0') until they were IFF_UP. But
when they are created by NM, although NM knows the ifindex the
platform ignores the interface until udev finds it. Thus immediately
after creating the interface in _internal_activate_device() it
won't be known to the platform, so the nm_device_is_available()
check that controls whether the device moves to DISCONNECTED
will fail. This prevents any activation and emits the message:
"Connection 'foo' is not available on the device %s at this time."
because the device is still in the UNAVAILABLE state.
danw asked why we care about IFF_UP for these devices, and I can't
remember why, and I don't think it makes sense to require now.
https://bugzilla.gnome.org/show_bug.cgi?id=746918
(cherry picked from commit 568a8d1da9)
Up to now, this code was correct. Later we will add another field
to NMPlatformIP4Route which causes the test to operate on
uninitialized data.
Instead of explicitly initializing the field, just clear the whole
struct.
(cherry picked from commit 4bdd83127d)
With NM_MORE_LOGGING disabled, we still want the compiler to evaluate
the argument list. By wrapping it in "if(FALSE)", we get compile time
checks, but the logging statement will be optimized out.
(cherry picked from commit cb6bafb9af)
Use _nm_log() in places that already checked whether logging
is enabled. No need to check again as done by nm_log().
(cherry picked from commit 4526b55a51)
Refactor the implementation of nm_route_manager_ip4_route_sync()
and nm_route_manager_ip6_route_sync().
- merge the implementations for IPv4 and IPv6.
- pre-sort the routes and iterate them in a way that we don't
need to lookup a route in other lists. Do this by iterating
two sorted lists at a time in a merge-sort way.
The runtime complexity of sync is now O(n*ln(n)).
- previously, the algorithm would merge routes it found in platform
to priv->ipx_routes. That was wrong, because then we loose the
information which routes we wanted to configure internally and which
are present externally.
Instead, priv->ipx_routes now contains all the routes that were
explicitly configured via sync(). Hence, it knows what should be
configured (@ipx_routes) and can compare to what is configured
(@plat_routes).
https://bugzilla.gnome.org/show_bug.cgi?id=740064
(cherry picked from commit 62c652c352)
Tests that use g_assert_expect_message() must initialize with
nmtst_init_assert_logging().
Otherwise, the caller can change the logging level via
NMTST_DEBUG=log-level=DEBUG,log-domains=DEFAULT
which breaks the assertions.
nmtst_init_assert_logging() allows the caller to turn of
checking of assertions via
NMTST_DEBUG=log-level=DEBUG,log-domains=DEFAULT,no-expect-message
Also, don't use g_message() in platform tests otherwise the test fail
because nmtst now sets g_log_set_always_fatal().
(cherry picked from commit 5fd3827e49)
Create a NMRouteManager singleton.
Refactor, no functional changes apart from change of log domain from
LOGD_PLATFORM to LOGD_CORE.
Subsequent commit will keep track of the conflicting routes, avoid overwriting
older ones with newer ones and apply the new ones when the old ones go away.
(cherry picked from commit 874e4a7595)
Previously for assumed connections we would never configure a default route.
That has serious problems for example in the following two scenarios:
- the default-route might have a limited lifetime from a previous
SLAAC/accept_ra setting. In this case, once we assume the connection
we must also ensure that we extend the lifetime of the default
route.
- the gateway could be received via DHCP/RA and it might change.
If we ignore default-routes for assumed connection we miss that
change.
The problem is that the notion of "assumed connection" wrongly combines
two conflicting goals (related bug bgo#746440):
a) have an external device that is entirely unmanged by NM.
b) do a seamless takeover of a previously managed connection at start,
but still fully manage.
This patch changes the handling of default-routes towards meaning b).
https://bugzilla.redhat.com/show_bug.cgi?id=1224291
(cherry picked from commit d51975ed92)
Since da708059da, we would pickup the
default-route as configured externally, except at those moments when
NM re-applys the IP configuration of the interface, such as during a
DHCP lease.
That allows the user to add/remove the default-route externally (iproute).
But still, at random times (DHCP lease), we will revert those external
changes.
Extend this, that if the connection is explicitly configured as
'never-default=yes', that it tells NM not to interfere with externally
added default-routes on this device. That means, NM will only remove
any preexisting default-routes when configuring the device a first
time.
On any later attempts, NM will assume whatever is configured there.
That makes sense because the user indicated not wanting NM to
manage a default-route on that device, so if something externally
added a default-route, assume that is what the user wants.
This only affects non-assumed connections, with 'never-default=yes'.
https://bugzilla.redhat.com/show_bug.cgi?id=1205405
(cherry picked from commit 98e50e358b)
When a connection had static IP addresses, an early event
from plaform would clear them from priv->con_ip4_config.
Fix that, by don't initializing priv->con_ip4_config
before we commit the first time.
https://bugzilla.gnome.org/show_bug.cgi?id=749052
Fixes: 557667df12
(cherry picked from commit 843205521f)
It would subtract the configuration from device confguration that's not yet
applied. This a the race where the loose the address while activating a
connection that has both IPv6 and IPv4 configuration.
Fixes: 557667df12https://bugzilla.gnome.org/show_bug.cgi?id=746066
(cherry picked from commit 2e99ddb7a7)
Even more eagerly pickup external default routes from the device.
For assumed devices we already picked up the default route.
(a) For assumed devices we already did not enforce the default route at all.
Instead it was always picked up by from the actualy system
configuration. Note that this is the case for assumed-generated
connections and for assuming existing connections.
That means that when NM assumes a connection at startup, it will never
actively manage the default route on that interface. It will only react
on what is present.
(b) For managed devices that have by configuration no default route, still pick up
the default route. That means, that even a device that is managed and
never-default=yes, can have the default route -- if configured externally.
(c) Only during a commit phase (i.e. when we have new configuraiton to be
applied), we enforce the default route or its absence.
(d) During any IP change event from platform, we again pickup whatever
is present. That means if you remove the default route from a managed
interface, NM will not re-add it until anything triggers (c).
This also means, that during the commit phase, we add default routes as
'synced' to the default-route-manager, but the following event from platform,
will change the route entry immediately to 'non-synced'. That is
expected and correct.
(cherry picked from commit da708059da)
When receiving IP changes via platform event, remove all missing
addresses and routes from our internal configurations (such as
wwan, vpn, dhcp).
The effect is that on the next commit, those addresses and routes will
not be re-added as they were explicitly removed by the user.
However on a new DHCP lease or similar events, the addresses will
be added anew.
Another important improvement is that the NMIPxConfig of the active
device reflects when addresses or routes get removed externally. Before
we would continue to expose those entires although they were not
actually configured on the device.
https://bugzilla.gnome.org/show_bug.cgi?id=740443
(cherry picked from commit 557667df12)
In the IPv4 case, we check whether we have a direct route to the gateway
also by looking at the configured addresses/subnets. That is correct,
because every IPv4 address also implies a subnet route.
For IPv6, we explicitly add all subnet routes manually (noprefixroute),
hence, we have a direct route exactly if we have it in our list.
Regardless of the configured IPv6 prefixes.
(cherry picked from commit 2c06449085)
Factor out code of the nm_ip4_config_subtract() and
nm_ip6_config_subtract() functions. The code can be reused in the
following commit.
(cherry picked from commit 92d800b2e3)
It's not uncommon to lookup a platform parameter with invalid
ifindex or ifname. Be more resilient and just return "no link found".
Fixes: e8e455817b
(cherry picked from commit 0a38352470)
Change nm_platform_link_get() to return the cached NMPlatformLink
instance. Now what all our implementations (fake and linux) have such a
cache internal object, let's just expose it directly.
Note that the lifetime of the exposed link object is possibly quite
short. A caller must copy the returned value if he intends to preserve
it for later.
Also add nm_platform_link_get_by_ifname() and modify nm_platform_link_get_by_address()
to return the instance.
Certain functions, such as nm_platform_link_get_name(),
nm_platform_link_get_ifindex(), etc. are solely implemented based
on looking at the returned NMPlatformLink object. No longer implement
them as virtual functions but instead implement them in the base class
(nm-platform.c).
This removes code and eliminates the redundancy of the exposed
NMPlatformLink instance and the nm_platform_link_get_*() accessors.
Thereby also fix a bug in NMFakePlatform that tracked the link address
in a separate "address" field, instead of using "link.addr". That was
a case where the redundancy actually led to a bug in fake platform.
Also remove some stub implementations in NMFakePlatform that just
bail out. Instead allow for a missing virtual functions and perform
the "default" action in the accessor.
An example for that is nm_platform_link_get_permanent_address().
(cherry picked from commit e8e455817b)
We must check if a conflicting route/address is configured on
*any* interface, not only on the target ifindex.
This at least restores the previous behavior. Note that this whole
check_reinstall_device_route() still has problems and it might
be better to move it all to NMRouteManager.
Fixes: 470bcefa5f
(cherry picked from commit 1bfade833a)
After doing all the refactoring, rename the ObjectType enum to NMPObjectType.
I didn't do this earlier to avoid problems with rebasing. But since I will
backport the platform changes to nm-1-0, this is the right time to get
the name right.
(cherry picked from commit 518cf76de7)
warning: function declaration isn’t a prototype [-Wstrict-prototypes]
In C function() and function(void) are two different prototypes (as opposed to
C++).
function() accepts an arbitrary number of arguments
function(void) accepts zero arguments
(cherry picked from commit 2dc27a99d7)