Commit graph

664 commits

Author SHA1 Message Date
Lubomir Rintel
3e2fce288a device: use the REMOVED reason when unmanaging the device while quitting
With the final removal the reason of NOW_UNMANAGED causes the cleanup on the
device to be run, which downs the device:

  #0  nm_platform_link_set_down (self=0x555555a29bb0, ifindex=1711) at platform/nm-platform.c:1111
  #1  0x00005555555d6ccf in nm_device_take_down (self=self@entry=0x555555c07c70, block=block@entry=1) at devices/nm-device.c:8175
  #2  0x00005555555df0c7 in _set_state_full (self=0x555555c07c70, state=NM_DEVICE_STATE_UNMANAGED, reason=NM_DEVICE_STATE_REASON_NOW_UNMANAGED, quitting=quitting@entry=0) at devices/nm-device.c:9825
  #3  0x00005555555dfa97 in nm_device_state_changed (self=<optimized out>, state=<optimized out>, reason=<optimized out>) at devices/nm-device.c:10084
  #4  0x00005555555e472c in nm_device_set_unmanaged_flags (self=<optimized out>, flag=flag@entry=NM_UNMANAGED_INTERNAL, unmanaged=unmanaged@entry=1, reason=reason@entry=NM_DEVICE_STATE_REASON_NOW_UNMANAGED)
      at devices/nm-device.c:8745
  #5  0x00005555555e54a9 in nm_device_set_unmanaged_quitting (self=<optimized out>) at devices/nm-device.c:8806
  #6  0x000055555565b1aa in remove_device (manager=manager@entry=0x555555a4a2c0, device=0x555555c07c70, quitting=quitting@entry=1, allow_unmanage=allow_unmanage@entry=1) at nm-manager.c:833
  #7  0x0000555555660b81 in nm_manager_stop (self=0x555555a4a2c0) at nm-manager.c:4389
  #8  0x00005555555b3f9b in main (argc=1, argv=0x7fffffffdba8) at main.c:493
2016-01-14 12:29:03 +01:00
Lubomir Rintel
cdc8a92b37 device: the unrealized devices can attempt to autoconnect 2016-01-13 18:10:25 +01:00
Lubomir Rintel
71f92bf72d device: trivial: streamline nm_device_autoconnect_allowed()
The function returns early when autoconnect is off, so there's no reason to
branch for that case below. The signal is only generated for autoconnect=true.
2016-01-13 18:10:17 +01:00
Beniamino Galvani
d26a8c2eed device: export nm_device_reactivate_ip{4,6}_config functions
nm_device_reactivate_ip6_config() will be used to reconfigure IPv6
addressing when a VLAN interface changes MAC.
2016-01-12 09:56:14 +01:00
Thomas Haller
a602b18f74 device: refactor virtual function NMDevice:unrealize_notify() to only clear properties
Change the meaning of unrealize_notify() similar to realize_start_notify(),
which only resets device properites during unrealize.
2016-01-11 14:05:49 +01:00
Thomas Haller
ec3613f27c device/trivial: rename virtual function NMDevice:unrealize() to unrealize_notify() 2016-01-11 14:05:49 +01:00
Thomas Haller
2550850f54 device: pass NMPlatformLink instance as const pointer 2016-01-11 14:05:49 +01:00
Thomas Haller
633e105455 device/trivial: rename realize/setup function in NMDevice 2016-01-11 14:05:49 +01:00
Thomas Haller
169c5b7a52 device: remove unused virtual function NMDevice:realize()
The idea of NMDevice:realize() was to
  (1) update the device properties
  (2) fail realization if some critical properties are missing

(1) is already done during nm_device_setup_start().
(2) was only implemented by NMDeviceVlan:realize(), but it
basically was just checking whether such a platform device exists.
Other implementations don't do that either and it opens up for a race
when the device gets deleted externally.
2016-01-11 14:05:49 +01:00
Thomas Haller
4c6b991bb0 device: move implementation of NMDevice:setup_start() to realize_start_setup()
All implementations of NMDevice:setup_start() in derived classes
invoke the parent implementation first. Enforce that by moving
NMDevice:setup_start() to realize_start_setup() and only notify
derived classes afterwards via NMDevice:realize_start_notify().
2016-01-11 14:05:49 +01:00
Thomas Haller
0311a0eae3 device: remove unused virtual function NMDevice:setup_finish() 2016-01-11 12:22:19 +01:00
Thomas Haller
1dbee32150 device: add realize_start_setup() function
Don't call the virtual function directly. Instead add
a wrapper function.
2016-01-11 12:22:19 +01:00
Thomas Haller
7db95727d5 device: refactor reapply_connection()
Reapplying a connection should not be done by iterating over and
(unsorted) @diffs array. Instead the order matters! E.g. first layer 2
before IP settings. Thus extracting those individual updates on a per-setting
base to different reapply_*() functions is more complicated, albeit incorrect
in complex cases. We need full control over how to reapply changes, one
after the other.

Also, once we start applying changes, we cannot really abort on error.
We can only continue best-effort and hope for the best.

Also, always reapply certain settings, even if the configuration doesn't
change. That means, if the user externally deletes a static IP address,
he can call reapply() to restore it. Even though he doesn't provide a
different setting to apply.

Also revert the changes to nm_device_reapply_settings_immediately().
Effectively there is little code that can be reused.

Add audit logging.
2016-01-10 23:14:29 +01:00
Lubomir Rintel
8adff4993c device: apply the firewall zone and metered state on Reapply()
Reuse some code with the immediate reapply mechanism.
2016-01-10 23:14:29 +01:00
Lubomir Rintel
02bf4db8bc device: add possibility to reapply the ipv6 settings 2016-01-10 23:14:29 +01:00
Lubomir Rintel
a5b6436a90 device: add possibility to reapply the ipv4 settings 2016-01-10 23:14:29 +01:00
Lubomir Rintel
1490c36bb9 device: add O.FD.NM.Device.Reapply() call
The introspection data and daemon stub. There's no settings that can be
reapplied at the moment.
2016-01-10 23:13:34 +01:00
Lubomir Rintel
21fa044df0 device: refactor the ip cleanup
Split it up and move upwards. It will be useful for runtime reconfig of
IPv4 configuration.
2016-01-10 23:12:48 +01:00
Beniamino Galvani
92149f223f device: wait for valid MAC before making ethernet devices available
In certain situations, ethernet links first appear with a zero MAC
address and then the MAC changes some time later. Currently NM does
not deal correctly with this scenario since it initializes wrong
@initial_hwaddr and @permanent_hwaddr on the device and tries to
immediately activate it.

To fix this, initialize the device's addresses only when the MAC
becomes valid and make the device available only at that point.
2016-01-07 11:53:05 +01:00
Beniamino Galvani
2a0a9aa2e4 device/trivial: split out nm_device_update_initial_hw_address() 2016-01-07 11:52:52 +01:00
Beniamino Galvani
44789e3291 core: simplify generation of default connection for new devices
Instead of using a signal for triggering the generation of a default
connection when the device becomes managed, let the manager wait for a
transition to UNAVAILABLE or DISCONNECTED states.

This partially reverts b3b0b46250 ("device: retry creation of
default connection after link is initialized").
2016-01-07 11:52:52 +01:00
Beniamino Galvani
ea1eb94d9b core: use nm_clear_g_signal_handler() where possible
Replacement was done with command:

spatch --sp-file nm_clear_g_signal_handler.cocci --in-place --smpl-spacing --dir src

where nm_clear_g_signal_handler.cocci contains:

@@
expression obj, id;
@@
- if (id) {
-    g_signal_handler_disconnect (obj, id);
-    id = 0;
- }
+ nm_clear_g_signal_handler (obj, &id);
2016-01-06 21:25:56 +01:00
Beniamino Galvani
f96abc8be5 core: always use gulong to store signal handler ids
We inconsistently use gulong,guint,int types to store signal handler
id, but the type returned by g_signal_connect() is a gulong.

This has no practical consequences because a int/guint is enough to
store the value, however it is better to use a consistent type, also
because nm_clear_g_signal_handler() accepts a pointer to the signal id
and thus it must be always called with the same pointer type.
2016-01-06 21:25:55 +01:00
Beniamino Galvani
fbd3286955 core,libnm: use nm_clear_g_source() where possible
Replacement was done with commands:

spatch --sp-file nm_clear_g_source.cocci --in-place --smpl-spacing --dir src
spatch --sp-file nm_clear_g_source.cocci --in-place --smpl-spacing --dir libnm

where nm_clear_g_source.cocci contains:

@@
expression e;
@@
- if (e) {
-    g_source_remove (e);
-    e = 0;
- }
+ nm_clear_g_source (&e);
2016-01-06 21:25:55 +01:00
Beniamino Galvani
ed536998f9 device: update @ip_iface only if IP interface exists
If @ip_ifindex is zero, the IP interface has disappeared and
there's no point in updating @ip_iface.

Actually, unconditionally updating @ip_iface is dangerous because it
breaks the assumption used by other functions (as
nm_device_get_ip_ifindex()) that a non-NULL @ip_iface implies a valid
@ip_ifindex. This was causing the scary failure:

  devices/nm-device.c:666:get_ip_iface_identifier: assertion failed: (ifindex)

https://bugzilla.redhat.com/show_bug.cgi?id=1268617
2016-01-05 18:36:46 +01:00
Lubomir Rintel
da1abaa1db device: reset the capabilities to class defaults when reseting them
Otherwise the lacking IS_SOFTWARE capability may cuase the connections not to
be available on software devices and the devices would get garbage-collected at
the end of unrealize().
2016-01-04 12:09:55 +01:00
Thomas Haller
444df2d30e rdisc: don't log error message when failing to create NDP socket
Let the caller do that, he already logs an ERR level message. Just
combine the messages.
2015-12-17 17:28:48 +01:00
Lubomir Rintel
a6ceb382e9 device: connect slave assumption recheck on external enslavement
The nm_device_master_add_slave() also modifies slave's master property which
impacts the ability to enslave. When called in reaction to external
master property change we now no longer call enslave_slave which used to queue
the recheck previously:

  # nmcli c add type bridge ifname br0
  # ip link add dummy0 type dummy
  # ip link set dummy0 up
  # ip link set dummy0 master br0  # We should recheck for assumed connection
                                   # here, since dummy0 can now be assumed.
2015-12-17 15:37:01 +01:00
Lubomir Rintel
2e22880894 device: don't remove the device from master if its link has no master
We only need to do that when we're replacing the master with a different
one. Just after the link creation is has no master and we'd remove it
from the master device here.
2015-12-16 18:53:27 +01:00
Lubomir Rintel
436ec5b8e3 device: remove the unreferenced unreal devices
When there's no connection that would use an unrealized device there's no more
reason to keep the device in memory. It's in fact a resource leak.
2015-12-14 12:51:49 +01:00
Lubomir Rintel
a22a109ad6 device: reset autoconnect when the device unrealizes
Fixes autoconnect after the device is realized again:

  # nmcli c add type team
  # nmcli c up team
  # nmcli d dis nm-team     # autoconnect is blocked
  # nmcli c del team        # the is unrealized
  # nmcli c add type team   # the device is realized again, not
                            # activating with the new connection
2015-12-14 12:49:35 +01:00
Lubomir Rintel
9ae0227591 device: don't tell the device to unconfigure if it's gone already
After the device is unrealized a lot of its properites are reset. Notably, it
doesn't have an ifindex anymore so there's nothing to unconfigure really. This
makes at least NMDeviceBond unhappy:

  (bond device with a slave is removed externally)

  NetworkManager[21022]: <info>  (bond0): device state change: activated -> unmanaged (reason 'unmanaged') [100 10 3]
  NetworkManager[21022]: nm_platform_link_release: assertion 'master > 0' failed

  Program received signal SIGTRAP, Trace/breakpoint trap.
  g_logv (log_domain=0x5555557592b1 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd370) at gmessages.c:1046
  1046              g_private_set (&g_log_depth, GUINT_TO_POINTER (depth));
  (gdb) bt
  #0  0x00007ffff4ec88c3 in g_logv (log_domain=0x5555557592b1 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd370) at gmessages.c:1046
  #1  0x00007ffff4ec8a3f in g_log (log_domain=log_domain@entry=0x5555557592b1 "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff4f3673d "%s: assertion '%s' failed")
      at gmessages.c:1079
  #2  0x00007ffff4ec8a79 in g_return_if_fail_warning (log_domain=log_domain@entry=0x5555557592b1 "NetworkManager", pretty_function=pretty_function@entry=0x55555575ea50 <__FUNCTION__.33801> "nm_platform_link_relea8
  #3  0x000055555560559a in nm_platform_link_release (self=0x555555a27bb0 [NMLinuxPlatform], master=master@entry=0, slave=slave@entry=3) at platform/nm-platform.c:1326
  #4  0x00005555555b506e in release_slave (device=<optimized out>, slave=0x555555b6d770 [NMDeviceEthernet], configure=<optimized out>) at devices/nm-device-bond.c:423
  #5  0x00005555555dab7b in nm_device_master_release_one_slave (self=self@entry=0x555555bf0cc0 [NMDeviceBond], slave=0x555555b6d770 [NMDeviceEthernet], configure=configure@entry=1, reason=reason@entry=
      NM_DEVICE_STATE_REASON_NOW_UNMANAGED) at devices/nm-device.c:1137
  #6  0x00005555555dadb6 in nm_device_master_release_slaves (self=self@entry=0x555555bf0cc0 [NMDeviceBond]) at devices/nm-device.c:2344
  #7  0x00005555555dd12f in nm_device_cleanup (self=self@entry=0x555555bf0cc0 [NMDeviceBond], reason=reason@entry=NM_DEVICE_STATE_REASON_NOW_UNMANAGED, cleanup_type=cleanup_type@entry=CLEANUP_TYPE_DECONFIGURE)
      at devices/nm-device.c:9133
  #8  0x00005555555de3ea in _set_state_full (self=self@entry=0x555555bf0cc0 [NMDeviceBond], state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=
      NM_DEVICE_STATE_REASON_NOW_UNMANAGED, quitting=quitting@entry=0) at devices/nm-device.c:9510
  #9  0x00005555555dedb7 in nm_device_state_changed (self=self@entry=0x555555bf0cc0 [NMDeviceBond], state=state@entry=NM_DEVICE_STATE_UNMANAGED, reason=reason@entry=NM_DEVICE_STATE_REASON_NOW_UNMANAGED)
      at devices/nm-device.c:9769
  #10 0x00005555555e11b4 in nm_device_unrealize (self=self@entry=0x555555bf0cc0 [NMDeviceBond], remove_resources=remove_resources@entry=0, error=error@entry=0x7fffffffd788) at devices/nm-device.c:2062
  #11 0x000055555565c9c5 in _platform_link_cb_idle (data=0x555555c6e2b0) at nm-manager.c:2055
  #12 0x00007ffff4ec179a in g_main_context_dispatch (context=0x555555a226c0) at gmain.c:3109
  #13 0x00007ffff4ec179a in g_main_context_dispatch (context=context@entry=0x555555a226c0) at gmain.c:3708
  #14 0x00007ffff4ec1ae8 in g_main_context_iterate (context=0x555555a226c0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3779
  #15 0x00007ffff4ec1dba in g_main_loop_run (loop=0x555555a22780) at gmain.c:3973
  #16 0x00005555555b3e5f in main (argc=1, argv=0x7fffffffdb18) at main.c:488
2015-12-11 17:23:51 +01:00
Lubomir Rintel
785c263c18 device: do the LL check when the device is disconnected
An IPv6 address might have been added externally and the device is yet to
traverse to a connected state.

On the other hand, the externally added devices still traverse through
DISCONNECTED state and we don't want to attempt the LL addition there. Let's
check if the link still exists instead.
2015-12-11 13:24:07 +01:00
Thomas Haller
a4de9187ff platform: return pointer to NMPlatformLink object for add functions
Let the link-add functions return the internal pointer to the platform
link object. Similar to link-get, which doesn't copy the link either.

Also adjust the sole users of the add-functions (create-and-realize)
to take the pointer.

Eventually we still copy the returned data, because accessing platform can
invalidate the returned pointer. Thus we don't actually safe any copying
by this (at least every use of the function currently leads to the data
being copied).
Still change it, because I think the API of NMPlatform should look like that.
2015-12-10 14:33:49 +01:00
Thomas Haller
2a14a28fe0 device: pass const NMPlatformLink instance to setup_start()/setup_finish()
NMPlatformLink is a plain struct (not a GObject, for which we usually
don't use const). We certainly don't want the functions to modify the
passed-in data.
2015-12-09 17:05:45 +01:00
Thomas Haller
590b9a830d device: accept UNKNOWN device types during create_and_realize()
There are the link-types NONE and UNKNOWN. NONE is a linktype that is never
returned by platform, but UNKNOWN is very much a valid (albeit unspecified)
type.

Effectively, create_and_realized() should create a link of a known type,
thus it should never return an UNKNOWN link type at this point. Still
change it because it feels more correct.
2015-12-09 16:57:39 +01:00
Beniamino Galvani
a448854b44 device/vxlan: support device creation 2015-12-09 16:36:46 +01:00
Lubomir Rintel
a5c42eeb45 device: don't try to match the spec against a device with no hwaddr
It could be an unrealized device.
2015-12-09 15:55:12 +01:00
Beniamino Galvani
4de8851eca device/macvlan: support device creation 2015-12-09 14:30:08 +01:00
Thomas Haller
b9a35b6913 device/trivial: rename variable 2015-12-09 12:49:29 +01:00
Thomas Haller
2d1d187493 device: add NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST flag
This generalizes _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER.
2015-12-09 12:08:40 +01:00
Beniamino Galvani
158c63eb2c device: move initialization of ifindex to constructor()
Device subclasses (for example NMDeviceWifi) can use the ifindex in
their constructor(), but the value now is set later in
parent class constructed(). This causes the following:

  nm_platform_wifi_get_capabilities: assertion 'ifindex > 0' failed

Fix this by initializing ifindex earlier in NMDevice's
constructor(). While at it, remove the

  nm_assert (pllink->type != NM_LINK_TYPE_NONE);

assertion, since pllink can be NULL there.

Fixes: 6db04dc206
2015-12-09 11:09:48 +01:00
Lubomir Rintel
7dbf821cb2 device: precisely match the link type to the platform device
The unrealized device's factory could be using one particular link type, don't
allow matching the device to a non-matching one.
2015-12-08 18:11:53 +01:00
Lubomir Rintel
6db04dc206 device: add link_type property
This is to make it possible for the device factories to indicate the desired
link type and make it possible to avoid matching the unrealized device to a
platform device of different link type.
2015-12-08 18:11:52 +01:00
Thomas Haller
1104110865 device: fix crash in master_ready() logging unset priv->master
Fixes: f45f702a5e
2015-12-07 21:36:16 +01:00
Thomas Haller
e1738c7c61 core: use define for NMDnsMasqManager's "state-changed" signal name 2015-12-07 19:53:14 +01:00
Thomas Haller
ee4ec4e600 core: use define for NMDevice's "state-changed" signal name 2015-12-07 19:53:14 +01:00
Thomas Haller
04c70c76bc device: cache pointer to private-data in NMDevice structure
We often lookup the private data and retrieve it via NM_DEVICE_GET_PRIVATE(),
which in turn calls G_TYPE_INSTANCE_GET_PRIVATE().

Instead cache the pointer to the private data.

There are up- and downsides:

 - requries additional sizeof(gpointer) bytes for each NMDevice.
 + retrieving the private pointer will be slightly faster.
 + easier debugging in gdb as it is currently often a pain to
   retrieve the private data.

But most importantly, the allows to change our common pattern
to first cache the private data in a variable @priv. That is
often cumbersome to write, especially for short functions.
This change gives us a choice to use self->priv directly.

Such a change should not be aimed for every class. Instead it makes
mostly sense for NMDevice, where it pays off better due to the
class' size and ubiquitous use.

https://mail.gnome.org/archives/networkmanager-list/2015-December/msg00017.html
2015-12-07 19:30:11 +01:00
Lubomir Rintel
2077dee582 device: fix a typo in assertion
It is well understood that world would implode if the device was its own master.

Fixes: f45f702a5e
2015-12-07 19:02:54 +01:00
Thomas Haller
229ea4547c device: don't pass void* pointer to NM_DEVICE_GET_PRIVATE() 2015-12-07 16:34:48 +01:00