If DHCP fails to renew or rebind a lease, fail the device since the
IP config is no longer valid. Commit e2b7c482 was actually wrong for
dhcp[4|6]_fail(), since (ip_state == IP_FAIL) will never be true if
DHCP has ever been started, as IP_FAIL is only set from
nm_device_activate_ip[4|6]_config_timeout(), which obviously will not
be called in DHCP code paths if DHCP has previously succeeded.
For PAN devices we create an unsaved connection if no matching
connection exists. After the device gets removed, we want to clean
up that connection, unless it was modified/saved in the meantime.
Before this was accomplished by creating a clone of the original
connection. When deciding whether the temporary connection was
modified, we would compare the current state with the original.
This can now be simplified, because we have the nm-generated flag
that gets cleared whenever the user modifies or saves the connection.
This code is also more robust, because the previous implementation
was a hack, but could not reliably detect whether the connection
was modified by the user.
Signed-off-by: Thomas Haller <thaller@redhat.com>
At a few places, we checked for nm_device_uses_generated_connection()
whether to touch the device or not. nm_device_uses_generated_connection() used
to look at the "nm-generated" property of the NMSettingsConnection.
We are about to change the meaning of "nm-generated", which will mean
"any connection generated by NM, for whatever reason".
Instead now use the new "nm-generated-assumed" connection flag that has
the meaning "nm-generated" used to have.
So rename nm_device_uses_generated_connection() to nm_device_uses_generated_assumed_connection()
which looks at the "nm-generated-assumed" flag instead.
Also, be more strict in nm_device_uses_generated_assumed_connection() to require
both an "nm-generated-assumed" connection *and* an active connection that is
nm_active_connection_get_assumed().
Signed-off-by: Thomas Haller <thaller@redhat.com>
In preparation for internal device types exposing factories too, it's
easier to have the device type that the factory creates be returned
by the factory object instead of the plugin, because internal device
types don't have plugins.
This requires that we create the factory objects earlier, which
further requires that any operations that trigger signals must be
moved out of each factory's construction path to a separate start()
function.
Instead of creating it in NMSettings, where we must use
NM_IS_DEVICE_ETHERNET() (not NM_DEVICE_TYPE_ETHERNET because various generic
devices masquerade as NM_DEVICE_TYPE_ETHERNET too), push knowledge
of which device types create default wired connections into the device
types themselves. This solves a problem with testcases where
libNetworkManager.a (which testcases link to) requires the symbol
nm_type_device_ethernet().
Instead of having basically the same code in a bunch of different
place to find helper programs, just have one place do it. Yes, this
does mean that the same sequence of paths is searched for all helpers
(so for example, dnsmasq will no longer be found first in /usr/local)
but I think consistency is the better option here.
https://bugzilla.gnome.org/show_bug.cgi?id=734131
NM keeps interfaces IFF_UP when possible to receive link layer
events like carrier changes. Unfortunately, the kernel also
uses IFF_UP as a flag to assign an IPv6LL address to the interface,
which results in IPv6 connectivity on the link even if the interface
is not supposed to be activated/connected.
NM sets disable_ipv6=1 to ensure that the kernel does not set up
IPv6LL connectivity on interfaces when they are not supposed to
be active and connected. Unfortunately, that prevents users from
manually adding IPv6 addresses to the interface, since they expect
previous kernel behavior where IPv6 is enabled whenever the
interface is IFF_UP.
Furthermore, interfaces like PPP and some WWAN devices provide
misleading information to the kernel which causes the kernel to
create the wrong IPv6LL address for the interface. The IPv6LL
address for these devices is obtained through control channels
instead (IPV6CP for PPP, proprietary protocols for WWAN devices)
and should be used instead of the kernel address. So we'd like
to suppress kernel IPv6LL address generation on these interfaces
anyway.
This patch makes use of the netlink IFLA_INET6_ADDR_GEN_MODE
attribute to take over assignment of IPv6LL addresses while
keeping the interface IFF_UP, to ensure there is only IPv6
connectivity when the user requests it.
To remain compliant with standards, if a user adds IPv6 addresses
externally, NetworkManager must also immediately add an IPv6LL
address for that interface too.
https://bugzilla.gnome.org/show_bug.cgi?id=734149
Change all DBUS_TYPE_G_UCHAR_ARRAY properties to G_TYPE_BYTES, and
update corresponding APIs. Notably, this means they are now refcounted
rather than being copied.
Update the rest of NM for the changes. The daemon still converts SSIDs
to GByteArrays internally, because changing it to use GBytes has lots
of trickle-down effects. It can possibly be changed later.
APIs that take arbitrary data should take it in the form of a pointer
and length, not a GByteArray, so that you can use them regardless of
what format you have the data in (GByteArray, GBytes, plain array,
etc).
Change all DBUS_TYPE_G_LIST_OF_STRING and DBUS_TYPE_G_ARRAY_OF_STRING
properties to G_TYPE_STRV, and update everything accordingly.
(This doesn't actually require using
_nm_setting_class_transform_property(); dbus-glib is happy to transform
between 'as' and G_TYPE_STRV.)
Make all mac-address properties (including NMSettingBluetooth:bdaddr,
NMSettingOlpcMesh:dhcp-anycast-addr, and NMSettingWireless:bssid) be
strings, using _nm_setting_class_transform_property() to handle
translating to/from binary form when dealing with D-Bus.
Update everything accordingly for the change, and also add a test for
transformed setting properties to test-general.
NMDeviceBond, NMDeviceBridge, and NMDeviceTeam all used basically the
same code to generate a default interface name. Move it into
nm_utils_complete_generic().
The virtual :interface-name properties (eg,
NMDeviceBond:interface-name) are deprecated in favor of
NMSettingConnection:interface-name, and nm_connection_verify() ensures
that their values are kept in sync. So (a) there is no need to set
those properties when we can just set
NMSettingConnection:interface-name instead, and (b) we can replace any
calls to the setting-specific get_interface_name() methods with
nm_connection_get_interface_name() or
nm_setting_connection_get_interface_name().
Since we enforce the fact that bond, bridge, team, and vlan
interface-name properties match NMSettingConnection:interface-name,
nm_connection_get_virtual_iface_name() can be replaced with
nm_connection_get_interface_name() basically everywhere.
The one place this doesn't work is with InfiniBand partitions (where
get_virtual_iface_name() was actually computing the name), but for the
most part we only need to care about the interface names of InfiniBand
partitions in places where we also already need to do some other
InfiniBand-specific handling as well, so we can use an
InfiniBand-specific method
(nm_setting_infiniband_get_virtual_interface_name()) to get it.
(Also, while updating nm_device_get_virtual_device_description(), fix
it to handle InfiniBand partitions too.)
Even if we never receive an RA, if there are manually-specified or external
addresses, consider IPv6 to complete successfully. No reason to fail IPv6
if we have IP configuration already, but RA doesn't respond. If RA shows
up again, we're still listening for it and will apply the config at that
time.
Reporter left SLAAC enabled (because it's default and requires being
explicitly turned off) and added manual IPv6 address. They expected that
address to be assigned very soon after starting the connection, but it was
not assigned.
This happened because NM waits for RA before assigning any IPv6 configuration,
including the manually specified addresses. In the reporters case, there was
no IPv6 router on the network, so NM waited indefinitely for a router
advertisement and never applied any IPv6 configuration.
It seems reasonable to apply any IPv6 configuration we have available, when
we have it. We already apply RA configuration before starting DHCP, and
apply DHCP configuration if/when we get that.
The IPv4 pre-commit hook was called right before the config was
committed, while the IPv6 one was called before commit in only
one case (from nm_device_activate_ip6_config_commit). The IPv4
behavior is the intended behavior.
Note that this doesn't have any actual effect yet, since nothing
actually implements the IPv6 pre-commit hook
For NMDeviceWifi and NMDeviceWimax, the printf format string for
nm_utils_complete_generic() was created based on ssid/nsp. Since
these input strings are untrusted, this is a serious bug.
Signed-off-by: Thomas Haller <thaller@redhat.com>
The fact that NMRemoteConnection has to be an NMConnection and
therefore can't be an NMObject means that it needs to reimplement bits
of NMObject functionality (and likewise NMObject needs some special
magic to deal with it). Likewise, we will need a daemon-side
equivalent of NMObject as part of the gdbus port, and we would want
NMSettingsConnection to be able to inherit from this as well.
Solve this problem by making NMConnection into an interface, and
having NMRemoteConnection and NMSettingsConnection implement it. (We
use some hacks to keep the GHashTable of NMSettings objects inside
nm-connection.c rather than having to be implemented by the
implementations.)
Since NMConnection is no longer an instantiable type, this adds
NMSimpleConnection to replace the various non-D-Bus-based uses of
NMConnection throughout the code. nm_connection_new() becomes
nm_simple_connection_new(), nm_connection_new_from_hash() becomes
nm_simple_connection_new_from_hash(), and nm_connection_duplicate()
becomes nm_simple_connection_new_clone().
Previously, src/nm-ip4-config.h, libnm/nm-ip4-config.h, and
libnm-glib/nm-ip4-config.h all used "NM_IP4_CONFIG_H" as an include
guard, which meant that nm-test-utils.h could not tell which of them
was being included (and so, eg, if you tried to include
nm-ip4-config.h in a libnm test, it would fail to compile because
nm-test-utils.h was referring to symbols in src/nm-ip4-config.h).
Fix this by changing the include guards in the non-API-stable parts of
the tree:
- libnm-glib/nm-ip4-config.h remains NM_IP4_CONFIG_H
- libnm/nm-ip4-config.h now uses __NM_IP4_CONFIG_H__
- src/nm-ip4-config.h now uses __NETWORKMANAGER_IP4_CONFIG_H__
And likewise for all other headers.
The two non-"nm"-prefixed headers, libnm/NetworkManager.h and
src/NetworkManagerUtils.h are now __NETWORKMANAGER_H__ and
__NETWORKMANAGER_UTILS_H__ respectively, which, while not entirely
consistent with the general scheme, do still mostly make sense in
isolation.
For devices where we don't set the hardware address at construct time,
the first call to nm_device_update_hw_address() was hitting a
return-if-fail.
Also, when updating the hardware address, we were leaking the old
value.
Now that we have nm_utils_hwaddr_matches() for comparing addresses
(even when one is a string and the other binary), there are now places
where it's more convenient to store hardware addresses as strings
rather than binary, since we want them in string form for most
non-comparison purposes. So update for that.
In particular, this also changes nm_device_get_hw_address() to return
a string.
Also, simplify the update_permanent_hw_address() implementations by
assuming that they will only be called once. (Since they will.)
Add nm_utils_hwaddr_matches(), for comparing hardware addresses for
equality, allowing either binary or ASCII hardware addresses to be
passed, and handling the special rules for InfiniBand hardware
addresses automatically. Update code to use it.
Include <linux/if_ether.h> and <linux/if_infiniband.h> from
nm-utils.h, to get ETH_ALEN and INFINIBAND_ALEN, and remove those
includes (as well as <net/ethernet.h> and <netinet/ether.h>, and
various headers that had been included to get the ARPHRD_* constants)
from other files where they're not needed now.