For externally managed interfaces, we create an in-memory connection
and keep the device with sys-iface-state=external.
When the user actively modifies the connection, we persist it to
storage. But we also must take over managing the device.
One problem is that nm_device_reapply() errors out if the device
is still activating. It's unclear how to reapply the connection
while the device is in the process of activation. So, if the user
modifies the created connection very quickly, reapplying the settings
will fail.
https://bugzilla.redhat.com/show_bug.cgi?id=1462223
Since commit 2b51d3967 "device: merge branch 'th/device-mtu-bgo777251'",
we always set the MTU for certain device types during activation. Even
if the MTU is neither specified via the connection nor other means, like
DHCP.
Revert that change. On activation, if nothing explicitly configures the
MTU, leave it unchanged. This is like what we do with ethernet's
cloned-mac-address, which has a default value "preserve".
So, as last resort the default value for MTU is now 0 (don't change),
instead of depending on the device type.
Note that you also can override the default value in global
configuration via NetworkManager.conf.
This behavior makes sense, because whenever NM actively resets the MTU,
it remembers the previous value and restores it when deactivating
the connection. That wasn't implemented before 2b51d3967, and the
MTU would depend on which connection was previously active. That
is no longer an issue as the MTU gets reset when deactivating.
https://bugzilla.redhat.com/show_bug.cgi?id=1460760
It's useless (and in some cases also harmful) to commit the
configuration to update the default route metric when the device has
no default route. Also, don't commit configuration for externally
activated devices.
https://bugzilla.redhat.com/show_bug.cgi?id=1459604
Don't log in a function that basically just inspects state, without
mutating it. Instead, pass the reason why a connection could not be
generated to the caller so that we have one sensible log message.
The device's RECHECK_ASSUME signal has only NMManager as subscriber
and it immediately calls recheck_assume_connection().
With the previous commit, recheck_assume_connection() always logs
a debug message, so we don't need this duplicate message anymore.
Originally 850c977 "device: track system interface state in NMDevice",
intended that a connection can only be assumed initially when seeing
a device for the first time. Assuming a connection later was to be
prevented by setting device's sys-iface-state to MANAGED.
That changed too much in behavior, because we used to assume external
connections also when they are activated later on. So this was attempted
to get fixed by
- acf1067 nm-manager: try assuming connections on managed devices
- b6b7d90 manager: avoid generating in memory connections during startup for managed devices
It's probably just wrong to prevent assuming connections based on the
sys-iface-state. So drop the check for sys-iface-state from
recheck_assume_connection(). Now, we can assume anytime on managed,
disconnected interfaces, like previously.
Btw, note that priv->startup is totally wrong to check there, because
priv->startup has the sole purpose of tracking startup-complete property.
Startup, as far as NMManager is concerned, is platform_query_devices().
However, the problem is that we only assume connections (contrary to
doing external activation) when we have a connection-uuid from the state
file or with guess-assume during startup.
When assuming a master device, it can fail with
(nm-bond): ignoring generated connection (IPv6LL-only and not in master-slave relationship)
thus, for internal reason the device cannot be assumed yet.
Fix that by attatching the assume-state to the device, so that on multiple
recheck_assume_connection() calls we still try to assume. Whenever we try
to assume the connection and it fails due to external reasons (like, the connection
no longer matching), we clear the assume state, so that we only try as
long as there are internal reasons why assuming fails.
https://bugzilla.redhat.com/show_bug.cgi?id=1452062
The state file should only be read initially when NM starts, that is:
during NMManager's platform_query_devices().
At all later points, for example when a software device gets destroyed
and re-realized, the state file is clearly no longer relevant.
Hence, pass the set-nm-owned flag from NMManager to realize_start_setup().
This is very much the same as with the NM_UNMANAGED_FLAG_USER_EXPLICT flag,
which we also read from the state-file.
curl must bind to the interface that has IP configuration, not the
underlying device. Without this commit, connectivity check fails on
certain connection types (PPPoE, WWAN).
Fixes: 9d43869e47
After a daemon restart, any software device is considered !nm-owned,
even if it was created by NM. Therefore, a device stays around even if
the connection which created it gets deactivated or deleted.
Fix this by remembering the previous nm-owned state in the device
state file.
https://bugzilla.redhat.com/show_bug.cgi?id=1376199
Note that:
- carrier_changed_notify() has only one implementation: NMDeviceEthernet
to call get_link_speed() when carrier comes back.
- currently, calling carrier_changed_notify() with carrier=FALSE
has no effect, because NMDeviceEthernet only acts on carrier=TRUE.
- when carrier appears, nm_device_set_carrier() will call
carrier_changed() right away. We only call carrier_changed()
with carrier=TRUE only at one place. The change merley moves
carrier_changed_notify() out of the function. Apart from
that it has no effect.
- when carrier disappears, previoulsy we would delay action for
4 seconds. Hence, we would delay carrier_changed_notify() as well
-- although it has no effect.
The last point is at least ugly. Fix it by moving
carrier_changed_notify() to nm_device_set_carrier().
If there is value in such a helper function (there is), then
it should go alongside the other nm_connection_get_setting*()
helpers. NMDevice is already large enough.
The plugins may use stuff from core, but not the other way around.
Including "bluetooth/nm-bluez-common.h" is wrong.
The UUID argument is always "nap" in the NAP case. We don't need
the flexibility that it might be anything else. Just drop it.
As far as NMDevice is concerned, it anyway wouldn't (or shouldn't
know what the uuid is. It says register, and NMBluez5Manager should
figure out the details.
Changes:
- merge reserve_shared_ip() into shared4_new_config().
shared4_new_config() needs to register release_shared_ip(). However, it
wrongly would always register release_shared_ip(), even for user-supplied
addresses. To fix that, we would need yet another argument to
reserve_shared_ip() and coupling it even more with shared4_new_config().
At that point, it's cleaner to just merge the two functions.
- only create the shared_ips hash when needed, and delete it when
it's empty. The idea is, that NetworkManager possibly runs for a long
time, and most of the time no shared connection is active. Just clean
up the empty hash while we don't need it.
Otherwise a device which was set as unmanaged (updated to the REMOVED
internal sys-state) will never update its own sys-state if later set
back as managed.
Manage either when setting explictly the device to managed either when
just upping a connection on an unmanaged device.
On cleanup, unconditionally release a device from its master if the
link is missing or it doesn't have a master, otherwise the master
would later try to release the slave, hitting the following assertion:
"nm_platform_link_release: assertion 'slave > 0' failed"
#0 g_logv
#1 g_log
#2 g_return_if_fail_warning
#3 nm_platform_link_release
#4 release_slave
#5 nm_device_master_release_one_slave
#6 slave_state_changed
#7 ffi_call_unix64
#8 ffi_call
#9 g_cclosure_marshal_generic
#10 g_closure_invoke
#11 signal_emit_unlocked_R
#12 g_signal_emit_valist
#14 _set_state_full
#15 nm_device_state_changed
#16 nm_device_unrealize
#17 _platform_link_cb_idle
#18 g_main_context_dispatch
#19 g_main_context_dispatch
#20 g_main_context_iterate
#21 g_main_loop_run
#22 main
Fixes: 9e8218f99ahttps://bugzilla.redhat.com/show_bug.cgi?id=1448907
Use nm_device_get_ip_ifindex() to obtain the right ifindex for the
device. Fixes the following:
nm_platform_ip4_address_get_all: assertion 'ifindex > 0' failed
#0 _g_log_abort () from target:/lib64/libglib-2.0.so.0
#1 g_logv () from target:/lib64/libglib-2.0.so.0
#2 g_log () from target:/lib64/libglib-2.0.so.0
#3 nm_platform_ip4_address_get_all (self=self@entry=0x1181020, ifindex=ifindex@entry=0) at src/platform/nm-platform.c:2640
#4 nm_ip4_config_capture (platform=0x1181020, ifindex=ifindex@entry=0, capture_resolv_conf=capture_resolv_conf@entry=0) at src/nm-ip4-config.c:271
#5 ip4_config_merge_and_apply (self=self@entry=0x1254a70, config=config@entry=0x0, commit=commit@entry=1) at src/devices/nm-device.c:5447
#6 activate_stage5_ip4_config_commit (self=0x1254a70) at src/devices/nm-device.c:8299
#7 activation_source_handle_cb (self=0x1254a70, family=family@entry=2) at src/devices/nm-device.c:4421
#8 activation_source_handle_cb4 (user_data=<optimized out>) at src/devices/nm-device.c:4358
#9 g_idle_dispatch () from target:/lib64/libglib-2.0.so.0
#10 g_main_context_dispatch () from target:/lib64/libglib-2.0.so.0
#11 g_main_context_iterate.isra () from target:/lib64/libglib-2.0.so.0
#12 g_main_loop_run () from target:/lib64/libglib-2.0.so.0
#13 main (argc=<optimized out>, argv=<optimized out>) at src/main.c:435
Fixes: a21b8882cc
with the rework in commit #87a3df2e572ed47b5f76f6d1cad63ce622296e21
the check of the return value of _device_activate () is no more needed.
Remove useless check and var.
ip link add name $'d\xccf\\c' type dummy
Use nm_utils_str_utf8safe_escape() to sanitize non UTF-8 sequences
before exposing them on D-Bus. The operation can be reverted client
side via nm_utils_str_utf8safe_unescape() or simply g_strcompress().
Note that this preserves all valid UTF-8 sequences as-is, with exception
of the backslash escape character and ASCII control characters. Thus, this
is a change in behavior for strings that contain such characters.
Note that nmcli is not changed to somehow unescape the string before
printing. As the string is not valid UTF-8 (or contains ASCII characters
that need escaping), they are not printable as-is, so unescaping before
printing makes little sense.
If the platform signaled that the external configuration changed (and
thus update_ipX_config() is scheduled) and we are doing a commit of
the new configuration, update priv->ext_ipX_config. Without this, the
commit will remove addresses added externally but not yet captured in
the external configuration.
https://bugzilla.redhat.com/show_bug.cgi?id=1449873
platform: signal: link changed: 2: eth0 <DOWN;broadcast,multicast> mtu ...
...
device[0x7f90c29c64d0] (eth0): bringing up device
...
platform: signal: link changed: 2: eth0 <UP,LOWER_UP;broadcast,multicast,up,running,lowerup> mtu ...
...
device (eth0): link connected
...
device[0x7f90c29c64d0] (eth0): add_pending_action (2): 'carrier wait'
Note how we schedule the pending action 'carrier-wait', although the device
already has carrier. That means, the pending action will not be removed
until timeout, 5 seconds later.
Avoid scheduling 'carrier-wait' if we already have carrier.
However, don't just add the pending action 'carrier-wait' only during
nm_device_bring_up(). Instead, always schedule the carrier_wait timeout.
This gives a grace period during which we keep setting 'carrier-wait' whenever
we have no carrier. This should prevent two cases:
- during nm_device_bring_up() the platform state might not yet have
caught up. If we don't add the pending action there, we will add
it a moment later when carrier goes away.
- bringing the interface up might cause carrier to get lost for a
moment (flapping). If that happens within the timeout, also add the
pending action.
nm_device_set_carrier_from_platform() is only called from two places.
- both check for NM_DEVICE_CAP_CARRIER_DETECT, so move that check
inside the function.
- drop the logging in realize_start_setup(). nm_device_set_carrier() already
does logging.
- always set the fake carrier in nm_device_set_carrier_from_platform().
For the fake carrer, we anyway expect it to be already TRUE in most
case, so usually this should have no effect.
Also emit a property changed signal. That is necessary to refresh the
D-Bus property.
Adding/Removing a pending action with assert_not_yet_pending/
assert_is_pending means that we expect that no action is taken.
Downgrade the logging level in those cases to <trace>.
Don't give the subclass the ability to override the parents
behavior. The parent implementation is not intended to allow
for that. Instead, restrict the flexibility of how the virtual
function integrates with the larger picture. That means, the
virtual function is only called at one place, and there is only
one implementation in NMDeviceEthernet (and it doesn't really
matter whether the implementation chains up the parent implementation
or not).
It's not the correct thing to do, but is the same behavior we've done
previously.
DAD is not even going to start until there's carrier and the client would
just wait indefinitely. Ideally, the client would choose not to waiat, but
it currently there's no way the client would discover what is going on.
https://bugzilla.redhat.com/show_bug.cgi?id=1446367
Set the @was_active flag for external activations with DHCP, so that
DHCP is retried multiple times in case of failure, as we do for
managed connections when the lease expires and for assumed
connections.
Fixes test: renewal_gw_after_dhcp_outage_for_assumed_var1
Fixes: e3113fdc4b
We check the return value of _get_stable_id(); when it is NULL
priv->ndisc would stay NULL too and we would crash when dereferencing
@error.
Actually, _get_stable_id() can never return NULL, so replace the check
with an assertion.
Most of the IPv6 methods require a non-tentative link local address
configured on the interface; we look at priv->ip6_config to determine
if such address exist. If the configuration is out-of-sync, we may
proceed with configuration when the link-local address does not exist
or is still tentative, especially because we toggle the "disable_ipv6"
sysctl parameter just before, which clears all IPv6 addresses on the
interface.
Ensure that priv->ext_ip6_config_captured is up-to-date before
continuing with the IPv6 configuration, and use it to determine
whether suitable addresses are present.
Fixes test: @ipv6_set_ra_announced_mtu
Fixes: 8f4caab601