Cache externally added IP details and represent them via the D-Bus
interface, and also merge them into the final device config to ensure
they aren't lost if DHCP renews or RA changes occur.
Add a flag to indicate that the device is owned by NM.
This is interesting for software/virtual devices, that were created by
NM and should be deleted when the interface gets deactivated.
This flag is not implemented as a glib property.
Maybe this flag can be consolidated with the managed flag. For now it is
unclear how to do it, so add this flag. It should be easy later to
replace it again.
https://bugzilla.gnome.org/show_bug.cgi?id=695705https://bugzilla.redhat.com/show_bug.cgi?id=953300
Signed-off-by: Thomas Haller <thaller@redhat.com>
libgsystem contains more than just the local allocation macros; in the
future we will likely want to make use of some of this such as the
structured logging support.
These devices don't have a platform device at creation time, thus
is_software wasn't getting set properly. Move the is_software
decision to constructed() because by this point, the iface and
ifindex (if present) will be known for all cases and thus we can
figure out if it's a software device or not in one place.
This backwards compatible patch adds the possibility to use new
nm_device_generate_connection() API via update_connection() virtual
method implementations in NMDevice subclasses.
Compatibility is achieved by first trying to use the older API and
match_l2_config() virtual method and only then moving on to
update_connection().
The nm_device_generate_connection() calls update_connection() to create
type-specific NMSetting instances and verifies the connection before
returning it. To avoid tinkering with NMSettingConnection in
update_connection() we use a class attribute called connection_type
which is used by nm_device_generate_connection() itself.
Known issues:
* nm_device_generate_connection() method doesn't implement DHCP lease
configuration matching. We shouldn't actually need it but if a use case
for that will come out, we can fix it later.
* nm_device_generate_connection() doesn't fill in the slave-specific
options.
* update_connection() is not implemented and connection_type is not set
in the subclasses. This will be fixed in individual patches.
* NMSetting's compare_property() implementations in combination with
NM_SETTING_COMPARE_FLAG_CANDIDATE are not yet fully ready thus rendering
false negatives in some cases. Same as above.
Acked-by: Dan Winship <danw@gnome.org>
Acked-by: Thomas Haller <thaller@redhat.com>
Whether an active connection is assumed or connected from scratch is
only important during nm_device_activate(). When the activation process
is set up, there's no difference from any other active connection.
Acked-by: Dan Winship <danw@gnome.org>
Acked-by: Thomas Haller <thaller@redhat.com>
Add a property on NMManager indicating that it is currently starting
up and activating startup-time/boot-time network connections.
"startup" is initially TRUE, and becomes FALSE once all NMDevices
report that they have no pending activity (eg, trying to activate,
waiting for a wifi scan to complete, etc). This is tracked via a new
NMDevice:has-pending-activity property, which is maintained partially
by the device itself, and partially by other parts of the code.
Software devices don't have a UDI until udev finds them, and since we need
to know about the software devices before udev finds them the UDI will be
missing. Instead of requiring a UDI on NMDevice creation, update the
property from the NMPlatform link change signal when udev does find the
device.
Now that a UDI is no longer required for device creation, software devices
added by NM would be created in the platform_link_added_cb() signal
handler triggered by the various software device creation methods in
system_create_virtual_device() (eg nm_platform_bridge_add() etc). Then
the NMDevice created in system_create_virtual_device() would be a duplicate
and cause problems when it was added. Since system_create_virtual_device()
needs to do setup on some devices, suppress the device creation from the
platform link added handler in this function.
Much of this is a hack which should be cleaned up later.
The unref in finalize is not needed, because the hash table gets already freed
in dispose.
Note that setting available_connections to NULL in dispose is not really
needed, because (altough dispose might be called more than once) there
is a guarded by "priv->disposed = TRUE;". But leave it for clearity in
case somebody tries to access the pointer (which shouldn't happen).
Signed-off-by: Thomas Haller <thaller@redhat.com>
If a device is removed, then trying to reset its IPv6 state will cause
nm_utils_do_sysctl() to log a warning since the path no longer exists.
So don't try to do it in that case.
The switch to combine IPv4 configs to arrive at the final config would
cause externally added addresses and routes to be removed from the
interface when a DHCP or LLv4 event came in, becasue the externally
added details weren't cached anywhere and thus would be dropped on the
IP changes.
When a VPN wanted to add some routes (like the host route for the
VPN gateway) it would add them itself and listen for parent device
events and re-add them if necessary. That's pretty fragile, plus
the platform blows away routes that aren't part of the IP config
that's getting applied.
So we might as well just have the VPN connection tell the parent
what the routes are, and have the parent device handle updating
the routing. The routes are through the parent device anyway,
and so are "owned" by the parent too.
Like IPv6, keep the DHCP/LLv4 config separate and combine it with the
NMSettingIP4Config to arrive at the final, combined IP4 config. This
brings the behavior in line with IPv6 code flow and will allow adding
the VPN routes config into the mix more easily.
It appears the kernel does not send notifications via netlink if the
default route is removed in some cases. This causes the platform
route cache to become stale, and thus when the default route is
reset by NM the platform thinks the route already exists, and does
not add it. But the route doesn't exist, becuase the kernel silently
removed it without telling anyone.
Fix that with a big hammer by flushing/refilling the route cache when
devices are deactivated (deletion of their addresses causes the default
route to be removed by the kernel) and when the default route is
updated by NM itself.
Pavel: if we find a more granular method, we should probably revert
this as the cache refill can be expensive.
Bluetooth device hardware addresses won't change during the lifetime
of the object (since that would mean a completely new device) and
they also won't have an ifindex because they aren't netdevices.
Various bits of the core periodically call nm_device_update_hw_address()
to update a device's hardware address, but this function expects that
any device with a hardware address also has an ifindex. Except that
Bluetooth devices don't because they aren't netdevices.
Modify the get_hw_address_length() function to return a boolean
indicating whether or not the address can ever change, and set that
for BT devices. nm_device_update_hw_address() then exits early if
there's no point in re-checking the hardware address, avoiding the
assertion.
https://bugzilla.gnome.org/show_bug.cgi?id=701744
The previous ignore-carrier rules did not work well with dynamic IP
(dhcp/slaac) connections. Change the rule so that only static IP
connections can be activated when carrier is not present (but both
static and dynamic connections will remain up when carrier is lost).
Callers of these functions now only care whether two IP configs are
different and not what specific property changed, so we can simplify
this code down to a simple comparison for equality, based on the hashing
that's already done for the DNS manager.
Note that this patch doesn't effectively change any code.
Functions moved from nm-system:
* nm_system_apply_ip?_config → nm_ip?_config_commit
* ip?_dest_in_same_subnet → nm_ip?_config_destination_is_direct
Functions moved from NetworkManagerUtils:
* nm_utils_merge_ip?_config → nm_ip?_config_merge_setting
Functions renamed (and moved down to form one group):
* nm_ip?_config_new_for_interface → nm_ip?_config_capture
(The rationale for the rename is that from the achitectural point of
view it doesn't matter whether the function creates a new object or
updates an existing one. After the rename, it's obvious that
nm_ip?_config_capture() and nm_ip?_config_commit() are counterparts of
each other.)
0652d9c596 changed IP states like this:
| old behaviour | new behaviour
---------------------------------------------------------
success | IP_DONE && config is not NULL | IP_DONE
failure | IP_DONE && config is NULL | IP_FAIL
But some failure paths was not updated.
nm_platform_*_sync() functions check the cached kernel configuration
items (addresses, routes) before adding addresses to the kernel.
Therefore we don't need to be so careful about pushing NetworkManager
configuration to the kernel.
This patch helps to avoid having to compare nm_ip[46]_config objects,
which should only be created when a configuration change is being
performed.
in nm_device_start_ip_check(), because it is called from the state handler
(nm_device_state_changed()).
Errors:
(devices/nm-device.c:5585):nm_device_state_changed: runtime check failed: (priv->in_state_changed == FALSE)
<info> (eth0): device state change: ip-check -> secondaries (reason 'none') [80 90 0]