When activating for example a team device which is to be enslaved to a
bridge, nm_device_activate_stage1_device_prepare() will postpone
stage 2.
In that case, we didn't register the "master-ready" of the team
device and thus never progressed the slave from stage2.
Reproduce:
# nmcli connection delete t-br0
# nmcli connection delete t-team0
nmcli connection add type bridge con-name t-br0 autoconnect no ifname i-br0 ip4 192.168.177.100/24 gw4 192.168.177.1
nmcli connection add type team con-name t-team0 autoconnect no ifname i-team0
nmcli connection modify id t-team0 connection.master i-br0 connection.slave-type bridge
nmcli connection up t-team0
For libnm library, "nm-dbus-interface.h" contains defines like the D-Bus
paths of NetworkManager. It is desirable to have this header usable without
having a dependency on "glib.h", for example for a QT application. For that,
commit c0852964a8 removed that dependancy.
For libnm-glib library, the analog to "nm-dbus-interface.h" is
"NetworkManager.h", and the same applies there. Commit
159e827a72 removed that include.
However, that broke build on PackageKit [1] which expected to get the
version macros by including "NetworkManager.h". So at least for libnm-glib,
we need to preserve old behavior so that a user including
"NetworkManager.h" gets the version macros, but not "glib.h".
Extract the version macros to a new header file "nm-version-macros.h".
This header doesn't include "glib.h" and can be included from
"NetworkManager.h". This gives as previous behavior and a glib-free
include.
For libnm we still don't include "nm-version-macros.h" to "nm-dbus-interface.h".
Very few users will actually need the version macros, but not using
libnm.
Users that use libnm, should just include (libnm's) "NetworkManager.h" to
get all headers.
As a special case, a user who doesn't want to use glib/libnm, but still
needs both "nm-dbus-interface.h" and "nm-version-macros.h", can include
them both separately.
[1] https://github.com/hughsie/PackageKit/issues/85
Fixes: 4545a7fe96
For certain types of connection as PPP and WWAN the IP interface is
created during stage3 (IP config) but we are setting the firewall zone
at the beginning of stage3 and thus the zone is only set on the
underlying interface.
Add a check at the start of IP check phase to ensure that the firewall
zone is set again if the device interface is different from IP
interface.
https://bugzilla.redhat.com/show_bug.cgi?id=1110465
Depending on the network and the values of the 'dad_transmits' and
'retrans_timeout_ms' sysctls, DAD for the IPv6LL address can take
quite a while. Obviously there must be some upper bound on the
timeout, but 5 seconds seems a bit low. In this case it was observed
to be ~12 seconds but the sysctl values are unknown. In any case,
we can't predict the network/config so being a bit more lenient here
makes sense.
https://bugzilla.redhat.com/show_bug.cgi?id=1101809
Always take a reference to the manager when scheaduling an asynchronous
operations. In fact, all callers want to keep the manager alive as long
as there are operations in progress.
Refactor NMFirewallManager to have consistent semantics about
asynchronous calls.
- the callback is always invoked exactly once, but never
synchronously when starting the operation.
- while cancelling the request, the callback is invoked
synchronously with respect to the cancel operation.
- you can cancel a request once (and once only).
- you cannot cancel the request once the callback is invoked.
- when disposing the object with requests pending, the
callbacks are invoked synchronously.
- Add a callback argument to nm_firewall_manager_remove_from_zone().
Otherwise, the user never knows whether a call is still pending and
cancellable (as complete operations cannot be cancelled).
In fact, it makes no sense trying to cancel a call if you don't care
about when it completes.
- get rid of PENDING_CALL_DUMMY. The dummy callback allows cancellation
any number of times. We want to catch wrong usage by asserting that an
operation is only cancelled once.
- nm_firewall_manager_cancel_call() doesn't need the manager argument.
Either the call-id is valid (and has a valid pointer to the manager),
or there is a bug and it is a dangling pointer.
If SIM in a modem is locked, ModemManager can't initialize SupportedIpFamilies
and NetworkManager will set the property to 0. ModemManager then updates the
property after the modem is unlocked, but NetworkManager did not watch changes
to the property. And that resulted in a connection failure:
(ttyUSB1): Failed to connect 'O2 Internet': Connection requested IPv4 but IPv4 is unsuported by the modem.
(ttyUSB1): device state change: prepare -> failed (reason 'modem-init-failed') [40 120 28]
https://bugzilla.redhat.com/show_bug.cgi?id=1263959
NetworkManager set wpa_supplicant's fragment_size option to 1300. But if MTU
was lower, wpa_supplicant failed with "l2_packet_send - sendto: Message too
long" due to fragmentation of EAP-TLS or EAP-PEAP packets.
Actually, MTU has to be 14 bytes bigger than the "fragment_size" parameter.
Ideally, wpa_supplicant would take MTU in the account and adjust the
fragmentation limit accordingly. See discussion in
http://lists.shmoo.com/pipermail/hostap/2015-August/033546.htmlhttps://bugzilla.gnome.org/show_bug.cgi?id=755145
- Reorder statements, to first g_return_if_fail() and log state-change.
- Also log a message when leaving _set_state_full() early due to missing firmware.
Clone the connection upon activation. This makes it safe for the user
to modify the original connection while it is activated.
This involves several changes:
- NMActiveConnection gets @settings_connection and @applied_connection.
To support add-and-activate, we constructing a NMActiveConnection with
no connection set. Previously, we would set the "connection" field to
a temporary NMConnection. Now NMManager piggybacks this temporary
connection as object-data (TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE).
- get rid of the functions nm_active_connection_get_connection_type()
and nm_active_connection_get_connection_uuid(). From their names
it is unclear whether this returns the settings or applied connection.
The (few) callers should figure that out themselves.
- rename nm_active_connection_get_id() to
nm_active_connection_get_settings_connection_id(). This function
is only used internally for logging.
- dispatcher calls now get two connections as well. The
applied-connection is used for the connection data, while
the settings-connection is used for the connection path.
- needs special handling for properties that apply immediately
when changed (nm_device_reapply_settings_immediately()).
Co-Authored-By: Thomas Haller <thaller@redhat.com>
https://bugzilla.gnome.org/show_bug.cgi?id=724041
Refactor agent-manager to always invoke the complete function for
nm_agent_manager_get_secrets().
In general, the complete function is always invoked asnychronously
when starting the operation. On the other hand, when cancelling the
operation or disposing the manager with pending operations, we now
(always) synchronously invoke the callback.
This makes it simpler for the user to reliably cancel the request
and perform potential cleanup.
This behavior bubbles up through NMSettingsConnection and NMActRequest,
and other callers that make directly or indicrectly make use of
nm_agent_manager_get_secrets().
Instead of having the call_id of type guint32, make it an (opaque)
pointer type.
This has the advantage of strong typing and avoids the possiblity
of reusing an invalid integer (or overflow of the call-id counter).
OTOH, it has the disadvantage, that after a call_id is disposed,
it might be reused for future invocations (because malloc might
reuse the memory).
In fact, it is always an error to use a call_id that is already
completed. This commit also adds assertions to the cancel() calls
that the provided call_id is a pending call. Hence, such a bug
will be uncovered by assertions (that only might not tigger in
certain unlikely cases where a call-id got reused).
Note that for NMAgentManager, save_secrets() and delete_secrets()
both returned a call_id. But they didn't also provide a callback when
the operation completes. So the user trying to cancel such a call,
cannot know whether the operation is still in process and he cannot
avoid triggering an assertion.
Fix that by not returning a call-id for these operations. No caller
cared about it anyway.
For NMSettingsConnection, also track the internally scheduled requests
for so that we can cancel them on dispose.
This way, the function matches the other names like nm_device_set_unmanaged().
Arguably, the name currently makes some sense. But future commits will make
nm_device_get_unmanaged() more to be a counterpart of nm_device_set_unmanaged().
If the metered property of a connection is changed, an activated
device associated to the connection must be updated immediately with
the new metered value.
https://bugzilla.gnome.org/show_bug.cgi?id=754409
If at the moment when spawning nm-iface-helper dhcp4/slaac
did not yet complete, we would not enable it.
That is wrong. If the connection indicates to use dhcp4/slaac,
it should be used by nm-iface-helper without considering the
current state on the device.
https://bugzilla.redhat.com/show_bug.cgi?id=1260243
A GObject interface, like a class, has two different C types
associated with it; the type of the "class" struct (eg, GObjectClass,
GFileIface), and the type of instances of that class/interface (eg,
GObject, GFile).
NetworkManager was doing this wrong though, and using the same C type
to point to both the interface's class struct and to instances of the
interface. This ends up not actually breaking anything, since for
interface types, the instance type is a non-dereferenceable dummy type
anyway. But it's wrong, since if, eg, NMDeviceFactory is a struct type
containing members "start", "device_added", etc, then you should not
be using an NMDeviceFactory* to point to an object that does not
contain those members.
Fix this by splitting NMDeviceFactory into NMDeviceFactoryInterface
and NMDeviceFactory; by splitting NMConnectionProvider into
NMConnectionProviderInterface and NMConnectionProvider; and by
splitting NMSettingsPlugin into NMSettingsPluginInterface and
NMSettingsPlugin; and then use the right types in the right places.
As a bonus, this also lets us now use G_DEFINE_INTERFACE.
If DHCP fails for an assumed connection, NetworkManager would
transition the device to the FAILED and then to the ACTIVATED state
(because it is assumed); hence if the DHCP server goes temporarily
down the device will go into a permanent state without IP
configuration.
Fix this and try DHCP again after some time when the connection
is an assumed one.
https://bugzilla.redhat.com/show_bug.cgi?id=1246496
This would cause the ip_vti0 generic device (that appears upon insertion of
ip_vti module during libreswan ipsec stack init) to go managed and brought UP.
Without addresses assigned the device would cause all the VPN traffic to
disappear in the oblivion.
Program received signal SIGSEGV, Segmentation fault.
0x0000555555646b59 in platform_link_added (self=self@entry=0x5555559fe1d0,
ifindex=<optimized out>, plink=plink@entry=0x555555b10a70)
at nm-manager.c:1889
1889 nm_log_warn (LOGD_HW, "%s: factory failed to create device: %s",
(gdb) bt
#0 0x0000555555646b59 in platform_link_added (self=self@entry=0x5555559fe1d0, ifindex=<optimized out>, plink=plink@entry=0x555555b10a70) at nm-manager.c:1889
#1 0x000055555564980c in nm_manager_start (self=0x5555559fe1d0)
at nm-manager.c:1988
#2 0x000055555564980c in nm_manager_start (self=0x5555559fe1d0, error=error@entry=0x7fffffffe658) at nm-manager.c:4212
#3 0x00005555555ae173 in main (argc=1, argv=0x7fffffffe7c8) at main.c:428
(gdb)
When a new link is detected, NM tries to generate a default "Wired
connection" in nm_settings_device_added(), but if the link has not
been initialized by udev yet the function returns early because
priv->unmanaged_flags = UNMANAGED_PLATFORM_INIT.
To be sure that a default connection is created is such situation, we
need to call again nm_settings_device_added() after link
initialization.
https://bugzilla.redhat.com/show_bug.cgi?id=1254089
Don't disconnect the device when the DHCP renewal fails and there are
already configured static IP addresses on the device. Instead, keep
the device up and try DHCP again after some time.
https://bugzilla.redhat.com/show_bug.cgi?id=1168388
The parent of a link (IFLA_LINK) can be in another network namespace and
thus invisible to NM.
This requires the netlink attribute IFLA_LINK_NETNSID which is supported
by recent versions of kernel and libnl.
In this case, set the parent field to NM_PLATFORM_LINK_OTHER_NETNS
and properly handle this special case.
The logging macros _LOGD(), etc. are specific to each
file as they format the message according to their context.
Still, they were cumbersome to define and their implementation
was repeated over and over (slightly different at times).
Move the declaration of these macros to "nm-logging.h".
The source file now only needs to define _NMLOG(), and either
_NMLOG_ENABLED() or _NMLOG_DOMAIN.
This reduces code duplication and encourages a common implementation
and usage of these macros.
Don't clear NMDevice @master in nm_device_cleanup() if the device link
is still enslaved because this causes an inconsistent state in which
the slave in included in the @slaves field of master device but
@master of slave device is NULL.
In such state, if the master link gets deleted, NM receives a change
event for each slave and a deletion event for the master; the change
events should also remove slaves from @slaves of master device, but
since their @master field is NULL the removal can't be performed.
Later, when the master deletion event is received, @slaves is not empty
in dispose() of NMDevice and the following assertion is triggered:
dispose: runtime check failed: (priv->slaves == NULL)
https://bugzilla.redhat.com/show_bug.cgi?id=1243371
When the DHCPv6 lease received from the server contains multiple
addresses, dhclient generates a new BOUND event for each of
them. Instead of overwriting the previous IP6 configuration for each
BOUND event, we should try to detect if the new configuration belongs
to the same lease and merge its addresses with the existing one in
such case.
This allows NetworkManager to configure multiple addresses on an
interface via DHCPv6.
https://bugzilla.gnome.org/show_bug.cgi?id=681764https://bugzilla.redhat.com/show_bug.cgi?id=1244293