Commit graph

565 commits

Author SHA1 Message Date
Thomas Haller
0e266e7c16 core: fix activation of slave when master is not active, but device exists
NM fails to activate a slave if the master device already exists
but has not active connection.

One way to reproduce, create a bond master/slave configuration and
ensure that the master device exists (e.g. by activating the bond, and
killing NM without taking down the device, or externally via `ip link add`).

If you try to activate the slave it will fail with the following message
(in nmcli):
  "Error: Connection activation failed: The active connection on MASTER is not a valid master for 'SLAVE'"
although MASTER is not active.

This also triggers the following assertion:

    #0  0x0000003370c504e9 in g_logv () from /lib64/libglib-2.0.so.0
    #1  0x0000003370c5063f in g_log () from /lib64/libglib-2.0.so.0
    #2  0x000000000047646a in is_compatible_with_slave (master=0x0, slave=slave@entry=0xc4aa60) at nm-manager.c:2193
    #3  0x000000000047e289 in ensure_master_active_connection (self=self@entry=0xc8d150, subject=0x7f23b80059e0, connection=connection@entry=0xc4aa60, device=device@entry=0xcac380, master_connection=master_connection@entry=0x0,
        master_device=master_device@entry=0xc9e800, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2395
    #4  0x000000000047eb4a in _internal_activate_device (self=self@entry=0xc8d150, active=active@entry=0xcc33b0, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2665
    #5  0x000000000047ecf2 in _internal_activate_generic (self=self@entry=0xc8d150, active=active@entry=0xcc33b0, error=error@entry=0x7fffa5cc4958) at nm-manager.c:2712
    #6  0x000000000047ef2b in _internal_activation_auth_done (active=0xcc33b0, success=<optimized out>, error_desc=0x0, user_data1=0xc8d150, user_data2=<optimized out>) at nm-manager.c:2848
    #7  0x0000000000466fa1 in auth_done (chain=0xcef020, error=0x0, unused=<optimized out>, user_data=<optimized out>) at nm-active-connection.c:603
    #8  0x00000000004753da in auth_chain_finish (user_data=0xcef020) at nm-manager-auth.c:88
    #9  0x0000003370c492a6 in g_main_context_dispatch () from /lib64/libglib-2.0.so.0
    #10 0x0000003370c49628 in g_main_context_iterate.isra () from /lib64/libglib-2.0.so.0
    #11 0x0000003370c49a3a in g_main_loop_run () from /lib64/libglib-2.0.so.0
    #12 0x0000000000429e65 in main (argc=1, argv=0x7fffa5cc4e48) at main.c:678

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-20 17:14:29 -05:00
Dan Winship
c4ca23137e core: fix lag in NMManager:state moving to CONNECTED_GLOBAL
Something changed at some point so that NMManager was now recomputing
its state after a connection was activated, but before NMPolicy had
decided whether to give that connection the default route, meaning
NMManager would set the state to CONNECTED_LOCAL rather than
CONNECTED_GLOBAL.

Fix this by watching the active connection :default and :default6
properties too, so we do the right thing regardless of what order the
AC properties change in.
2014-06-06 15:33:03 -04:00
Dan Williams
7eaaa6a475 core: block on dispatcher scripts when quitting
Like VPN connections, block on dispatcher scripts when quitting.  Since
the event loop is no longer running we can't schedule callbacks.
2014-06-06 13:43:46 -05:00
Dan Williams
c93ae45b42 core: don't do anything interesting in NMDevice dispose()
The NMDevice dispose() function contained some badly-duplicated logic
about when to deactivate a device on its last ref.  This logic should
only run when the device is removed by the manager, since the  manager
controls the device's life-cycle, and the manager knows best when to
clean up the device.  But since it was tied to the device's refcount,
it could have run later than the manager wanted, or not at all.

It gets better.  Dispose duplicated logic that was already done in
nm_device_cleanup(), and then *called* nm_device_cleanup() if the
device was still activated and managed.  But the manager already
unmanages the device when removing it, which triggers a call to
nm_device_cleanup(), takes the device down, and resets the IPv6
sysctl properties, which dispose() duplicated too.  So by the time
dispose() runs, the device should already be unmanaged if the
manager wants to deconfigure it, and most of the dispose() code
should be a no-op.

Clean all that up and remove duplicated functions.  Now, the flow
should be like this:

1) manager decides to remove the device and calls remove_device()
2) if the device should be deconfigured, the manager unmanages
   the device
3) the NMDevice state change handler tears down the active connection
   via nm_device_cleanup() and resets IPv6 sysctl properties
4) when the device's last reference is finally released, only internal
   data members are freed in dispose() because the device should
   already have been cleaned up by the manager and be unmanaged
5) if the device should be left running because it has an assumable
   connection, then the device is not unmanaged, and no cleanup
   happens in the state change handler or in dispose()
2014-06-06 13:43:45 -05:00
Dan Williams
4b6f0d50a4 core: fix deactivation of assumed connections on device removal (bgo #729833)
The following procedure leaves an NMActiveConnection around for a deactivated
device, which causes errors in libnm-glib clients when they cannot create the
GObject for the non-existent device of the AC.

1) allow a device which can assume connections to be activated
2) stop NM, which should leave the device's IP configuration up
3) start NM and allow it to assume the device's existing connection
4) remove the device, either by unplugging it or 'rmmod'

The device is removed by nm-manager.c::remove_device(), but the device object
is not moved to UNMANAGED state, leaving the NMActiveConnection completely
unaware the device has gone away.

The nm-manager.c::remove_device() code did not correctly handle moving a
forcibly removed (eg, by unplugging or 'ip link del' or 'rmmod') device to
the UNMANAGED state when the device was active with an assumed connection.
To fix this, make the conditions when the device should be deactivated
on removal much more explicit.

A device should be deactivated on removal if:

1) it is forcibly removed, eg by the kernel network interface being
removed due to 'ip link del' or hotplugging, or internally by NM due
to a parent WWAN interface taking priority over a WWAN ethernet interface

2) if the device cannot assume connections, in which case NetworkManager
must have activated the device and since we cannot assume the connection
on restart, we should deactivate it

3) if the device is not activated, to ensure that its IPv6 parameters
and other things get reset to the pre-NetworkManager values

https://bugzilla.gnome.org/show_bug.cgi?id=729833
2014-06-06 13:43:45 -05:00
Dan Williams
4809898e08 trivial: simplify nm_device_set_is_nm_owned()
Nothing used its return value or passed FALSE.
2014-06-06 13:43:45 -05:00
Dan Williams
b4c368692d core: let NMDevice export itself
Saves some code and a memory allocation.
2014-06-06 13:43:45 -05:00
Dan Williams
a2fc57beef trivial: remove redundant check
check_if_startup_complete() already checks priv->startup and returns
if it's FALSE.  This if() is redundant.
2014-06-06 13:43:44 -05:00
Thomas Haller
6f2b6a6745 core: fix wrong g_return_if_fail() statement when value should be returned in NMManager:assume_connection()
CC       nm-manager.lo
  nm-manager.c: In function 'assume_connection':
  nm-manager.c:1605:345: error: 'return' with no value, in function returning non-void [-Werror=return-type]
    g_return_if_fail (nm_device_get_state (device) >= NM_DEVICE_STATE_DISCONNECTED);

Minor error, introduced by commit f229f4e201.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-06-06 16:37:52 +02:00
Dan Winship
f229f4e201 core: re-attempt connection assumption when the device state changes
If the initial attempt to assume a connection on a device fails, and
the device remains un-activated, but then something changes its
configuration externally, try to generate a new connection and assume
that.
2014-06-06 10:11:19 -04:00
Dan Winship
14048089a1 settings: add 'nm_generated' flag on NMSettingsConnection
Add 'nm_generated' flag on NMSettingsConnection, and have NMManager
set it on generated connections that it assumes.
2014-06-06 10:11:19 -04:00
Dan Williams
c4dd68bce9 core: remove unused 'error' argument to check_connection_compatible()
Nothing uses the error, so simplify some code and save 5K (0.45%) in
binary size.
2014-05-30 13:49:30 -05:00
Dan Williams
e62ac0d469 devices: simplify plugin type checking
Instead of having a GObject property and a factory function to get
the plugin's device type, just use the factory function, since it
always has to be around.
2014-05-13 13:50:25 -05:00
Dan Williams
92be78c905 core: log when creating Generic device when a plugin is missing
Log when a plugin is missing for link types that should have plugins.
2014-05-13 13:50:25 -05:00
Dan Williams
d877551d0a wimax: recognize WiMAX devices as Generic if no WiMAX plugin is loaded 2014-05-13 13:50:25 -05:00
Thomas Haller
c714f7ad53 core: refactor to return const GSList * from nm_manager_get_devices()
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-05-13 13:50:25 -05:00
Dan Williams
06e3c6d02f wifi: make Wi-Fi support a plugin
Make Wi-Fi support a plugin using the new device factory interface.
Provides a 7% size reduction in the core NM binary.

        Before    After
NM:    1154104  1071992  (-7%)
Wi-Fi:       0   110464

(all results from stripped files)
2014-05-13 12:38:43 -05:00
Dan Williams
b46b28d18f wifi: remove old ipw rfkill polling functionality
Older Intel "ipw" devices (ipw2100, ipw2200, and ipw2915) only gained
kernel rfkill subsystem integration with 2.6.33.  Before then their
custom rfkill functionality had to be polled via sysfs.  Since we now
require at least a 3.x kernel, remove this old code.
2014-05-13 12:06:58 -05:00
Dan Williams
b732240026 core: remove the HostnameProvider interface
It's only used to keep the DHCPManager up-to-date with hostname changes,
and that can be accomplished in much less code by just having NMManager
set a hostname on the DHCPManager itself.
2014-05-09 15:33:32 -05:00
Dan Williams
5d8197a80b core: ignore modem management service state in rfkill handling
rfkill handling should only pay attention to actual rfkill, since
rfkill is global but the modem management service state is per-device.
Thus calculating a global state from multiple devices is very
likely to get things wrong.

Remove all of the code that used to handle that sort of thing,
which means removing the 'enable-changed' signal from the Modem
device, since now nothing external to the modem device should
need to care whether it's enabled internally or not.
2014-05-06 14:15:50 -05:00
Dan Williams
876ec0c755 rfkill: toggle WWAN rfkill state on user enable/disable
Poke the kernel's WWAN rfkill state when the user changes our
WWANEnabled property, the same as we do for WiFi.  Also restore
saved WWAN state on startup, as we do for WiFi.  No good reason
why WWAN should be different here.
2014-05-06 14:15:50 -05:00
Thomas Haller
09d3c833fd platform: refactor signals by combining added/changed/removed
Before platform raised 3 signals for each object type. Combine
them into one and add a new parameter @change_type to distinguish
between the change type.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-05-03 03:44:22 +02:00
Dan Winship
1218b7e0c7 core: leave wake-on-LAN devices up over suspend/resume
Taking down a wake-on-LAN device before suspending will effectively
disable wake-on-LAN. So don't do that.

Based on a patch from Stanislaw Gruszka.

https://bugzilla.gnome.org/show_bug.cgi?id=712745
https://bugzilla.redhat.com/show_bug.cgi?id=826652
https://bugzilla.redhat.com/show_bug.cgi?id=1025009
2014-04-17 12:48:20 -04:00
Thomas Haller
ef770ca450 core: refactor NMManager by adding function for converting NMState to string
This will be especially nice, with lazy evaluation for NM logging.

Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-04-15 18:12:14 +02:00
Jiří Klimeš
583eba3828 core: sort connections in descending timestamp order on take-over (rh #1067712)
When assuming the connections on restart we want to prefer more-recently-used
connections. That's why we have to sort connections according to timestamps in
descending order. That means connections used more recently (higher timestamp)
go before connections with lower timestamp.

https://bugzilla.redhat.com/show_bug.cgi?id=1067712
2014-04-11 08:58:28 +02:00
Dan Williams
79a7e46bfd core: unregister removed devices from D-Bus
Instead of waiting until the device is disposed and dbus-glib does
it for us, remove them when the Manager is done with them.  If
something (like pending D-Bus calls) holds a reference to the device
when the Manager removes it, the device would previously still
service method calls until all references are released.  When
the device is removed, it's dead, and it shouldn't be exported
anymore.
2014-04-09 12:33:26 -05:00
Dan Williams
de5c91ea0f core: split user managed preference (unmanaged specs) out from internal management
We'll want to track internal management separately in the future, so split out
user management (eg, whether the device has been explicitly marked unmanaged
by the user).
2014-04-07 09:52:07 -05:00
Dan Williams
6c299bc19b core: convert unmanaged bits to flags
Instead of tracking unmanaged-ness in a couple variables (and because
I'd like to add one for user-unmanaged later) let's do it in a single
flags variable, and consolidate setting of the unmanaged states in one
place.
2014-04-07 09:52:07 -05:00
Mikhail Efremov
194b14e398 core: don't generate a connection for unmanaged devices 2014-04-07 09:52:06 -05:00
Dan Williams
1bf2ffb61e core: ensure activation does not disconnect private connections
If two users had the ability to control networking, and user1 started
a private connection which user2 cannot see, user2 could start their
own connection and disconnect user1's connection.  This is not
consistent with device disconnection.  A user who cannot see a
connection should not be able to start/stop it, even if they are
allowed to control networking in general.
2014-03-31 18:02:11 -05:00
Dan Winship
acb6a0d305 core: update NMManager:devices before emitting notify::devices (rh #1078720)
NMClient's "devices" property was getting out of sync because the
daemon was emitting "notify" before actually changing the property
value. This resulted in problems with re-activating virtual devices
that had previously been deactivated in gnome-control-center and
anaconda. (And probably gnome-shell and nm-applet?)
2014-03-27 12:16:46 -04:00
Dan Williams
e4bcfc20ca core: export ActiveConnection before handing it to the device (bgo #723783)
The AC doesn't get a D-Bus path until it's exported, but that happens after
it's handed to the Device it will be activated on.  The Device emits a
PropertyChanged event when it's handed the AC, but it ignores ACs that
aren't exported yet.  Thus when activating, the Device doesn't emit the
AC's path at all in the ActiveConnection property because it's NULL.

Fix that by exporting the AC immediately before starting activation
with it.

Second, move the notification of the Device.ActiveConnection property
to be emitted along with the state change to PREPARE instead of long
before it.  While we don't guarantee signal ordering in general, this
seems like a more correct ordering.

https://bugzilla.gnome.org/show_bug.cgi?id=723783
2014-03-20 19:26:40 -05:00
Dan Winship
398080640e core: warn if multiple plugins for the same type are installed
If we find multiple plugins for the same type (eg, because the user
previously installed the "atm" and "bt" plugins, and didn't delete
them), log a warning.
2014-03-19 14:56:47 -04:00
Dan Williams
23a5ae2f44 wifi: bypass available check for hidden APs during activation (rh #1069844)
Because not all clients set the 'hidden' property in a connection for
hidden/non-SSID-broadcasting networks, they may not show up in
the device's available-connections property.  After the
PendingActivation object removal, all activations require the
connection to be in available-connections, and thus hidden SSID
networks could not be activated.

Unfortunately check_connection_available() is used both during
activation and to populate the available-connections array, but we
only want to special-case activation paths, and still ensure that
SSIDs not found in the scan list are not in available-connections.

To make it clear this is a WiFi only hack, and that we should
remove it at some point in the future, create another class method
specifically for hidden WiFi and use that in activation paths to
special-case hidden WiFi connection activation.
2014-03-12 08:42:55 -05:00
Dan Winship
42df06e575 platform, devices: add support for vxlan devices
Since vxlan is new-ish, and vxlan IPv6 support in particular has only
been in the kernel since 3.11, we include our own copy of the vxlan
netlink constants rather than depending on the installed headers.
2014-03-06 09:48:15 -05:00
Thomas Haller
950cb2c44f core: rename function nm_active_connection_get_name() to nm_active_connection_get_id()
Signed-off-by: Thomas Haller <thaller@redhat.com>
2014-03-05 21:15:20 +01:00
Dan Winship
4753dff29e core: add some assertions to avoid clang analyzer false positives 2014-03-05 11:20:54 -05:00
Dan Williams
1d5847c8a6 core: match IPv4 'disabled' method to 'auto' when device has no link
If IPv4 configuration did not succeed or the device has no IPv4 addresses
when NM restarts, it will detect the existing device configuration as
'disabled'.  This can happen when a bridge has no slaves and thus cannot
perform IPv4 addressing because it has no carrier (since bridge carrier
status depends on slave carriers).  When NM starts or restarts, it
sees the bridge has no IPv4 address and assumes the IPv4 method is
'disabled'.  This creates a new connection, which blocks any slave
connections from activating if they specify their master via UUID
 (since the bridge's active connection is generated).

Fix this by allowing matches from 'disabled' to 'auto' if the device
has no carrier, and there are no other differences between the
original and the candidate connections.
2014-03-04 15:21:58 -06:00
Dan Williams
2fe5ebe21c core: correctly handle pre-activation dependency failure (rh #1069695)
Dependencies may fail before the activation actually starts, like
when a software device gets removed while the activation is
scheduled but before it has started.  In these cases, the
activation request should fail.
2014-03-04 15:21:29 -06:00
Dan Williams
b7598bbb8c core: ensure ActiveConnections stay alive over activation paths
With some upcoming changes, ActiveConnection objects could change to
DEACTIVATED state during activation, for example if the AC's device
was removed while the AC was being authorized.

To ensure the AC stays alive and is not used after being freed,
keep a reference to the AC across authorization operations.
2014-03-04 15:21:29 -06:00
Dan Williams
aeb1e103d8 mobile: make WWAN support a plugin
Make WWAN support a plugin using the new device factory interface.
Provides a 5% size reduction in the core NM binary.

     Before    After
NM: 1187224  1125208  (-5%)
MM:       0   100576

(all results from stripped files)
2014-03-03 09:32:41 -06:00
Dan Williams
a9591aecaf bluez: make Bluetooth support a plugin
Make Bluetooth support a plugin using the new device factory interface.
Provides a 5% size reduction in the core NM binary.

     Before   After
NM: 1253016 1187224 (-5%)
BT:       0   85752

(all results from stripped files)
2014-03-03 09:32:41 -06:00
Dan Williams
71a52347f3 atm: make ADSL support a plugin
Make ADSL support a plugin using the new device factory interface.
Provides a 1% size reduction in the core NM binary.

      Before    After
NM:  1265336  1253016  (-1%)
ATM:       0    27360

(all results from stripped files)
2014-03-03 09:32:41 -06:00
Dan Williams
2a04df856b devices: rework device plugin interface to be more flexible
In preparation for making WWAN and Bluetooth plugins, rework
the device plugin interface to meet those plugins' needs and
port WiMAX over in the process.
2014-03-03 09:32:41 -06:00
Dan Williams
8e9b9fe423 mobile: convert to device removed signals
Instead of having NMManager listen directly to the ModemManager
for modem removal signals, have the NMDeviceModem and NMDeviceBt
listen for them (since they obviously have a pointer to the backing
NMModem object) and then re-emit any necessary device removal
signals to the manager.
2014-03-03 09:32:40 -06:00
Dan Williams
ee66964208 core: allow devices to indicate when they should be removed
Devices created by plugins will use this to indicate when their
backing resources have disappeared, at which point the manager
should remove them.
2014-03-03 09:32:40 -06:00
Dan Williams
fd3fe2200c core: add nm_connection_provider_get()
In reality the connection provider (NMSettings) is always the same
object, and some device plugins need access to it.  Instead of
cluttering up the device plugin API by passing the provider into
every plugin regardless of whether the plugin needs it, create
a getter function.
2014-03-03 09:32:40 -06:00
Dan Williams
fe6b86a078 core: don't ref the Manager singleton
The OLPC mesh code did rely on nm_manager_get() referencing the
singleton when returning it, but all other callers of nm_manager_get()
did not.  Thus the manager's refcount would always increase and
almost never decrease.  Fix the refcounting so that the manager
always has only one ref, and it's lifetime is controlled by
main() and nothing else.
2014-03-03 09:32:40 -06:00
Dan Williams
4040198b47 core: queue re-activations to allow DEACTIVATING state
If a device is already activated, queue the new activation to allow
the transition through the DEACTIVATING state.

---

Also remove the "HACK" bits in nm_device_deactivate(). This hack was
added on 2007-09-25 in commit 9c2848d.  At the time, with user settings
services, if a client created a connection and requested that NM
activate it, NM may not have read the connection from the client over
D-Bus yet.  So NM created a "deferred" activation request which waited
until the connection was read from the client, and then began activation.

The Policy watched for device state changes and other events (like
it does now) and activated a new device if the old one was no longer
valid.  It specifically checked for deferred activations and then
did nothing.  However, when the client's connection was read, then
nm-device.c cleared the deferred activation bit, leading to a short
period of time where the device was in DISCONNECTED state but there
was no deferred activation, because the device only changes state to
PREPARE from the idle handler for stage1.  If other events happened
during this time, the policy would tear down the device that was
about to be activated. This early state transition to PREPARE
worked around that.

We need to remove it now though, because (a) the reason for its
existence is no longer valid, and (b) _device_activate() may now
be called from inside nm_device_state_changed() and thus it cannot
change to a new state inside the function.
2014-02-25 18:03:02 -06:00
Dan Williams
9d50e9dbd9 mobile: fix removal of ethernet interfaces owned by modems
If the kernel doesn't tag a modem's ethernet interface with
DEVTYPE=wwan then NetworkManager has no idea that's a modem
(and cannot be used until connected via the control port).
Since DEVTYPE=wwan devices get ignored by NM, so should these
interfaces when NM knows they are modems.

That got broken at some point for ModemManager1, because the
data port isn't read until the modem is connected.  NM only
looked for and removed the data-port-as-ethernet-device when
the modem was added, long before the MM1 data port was found.

ModemManager does provide a list of ports owned by the modem
though, which we can use at modem addition time to remove
an ethernet device that is controled by the modem.
2014-02-21 09:45:06 -06:00