Some drivers (brcmfmac) don't change the MAC address right away.
NetworkManager works around that by waiting synchronously until
the address changes (commit 1a85103765).
wpa_supplicant on the other hand, only re-reads the MAC address
when changing state from DISABLED to ENABLED, which happens when
the interface comes up.
That is a bug in wpa_supplicant and the driver, but we can work-around by
waiting until the MAC address actually changed before setting the interface
IFF_UP. Also note, that there is still a race in wpa_supplicant which might
miss a change to DISABLED state altogether.
https://bugzilla.gnome.org/show_bug.cgi?id=770504https://bugzilla.redhat.com/show_bug.cgi?id=1374023
This was added by commit 4de8851eca, probably
by copying from NMDeviceVlan. It's not clear why a netlink request to
set the device IFF_UP would fail, or why that warrants a retry.
This retry loop was added by commit dc6341acec.
But I suspect, that the main-point there was not to retry the netlink
request to set the interface up. Why would that fail, and why would
a failure to set the interface up require a retry?
I think it was added to wait for carrier. But waiting for carrier was
later dropped with commit 5074898591
and it is not clear why we would wait for carrier at all -- we don't
do that for other device types either.
Instead of letting the sub-class check the "enabled" state, let
it be handled by nm_device_bring_up().
Note that nm_device_get_enabled() only has two implementations:
NMDeviceModem:bring_up() and NMDeviceWifi:bring_up().
The virtual function NMDevice:set_enabled() has two implementations:
NMDeviceModem and NMDeviceWifi. Likewise, the get_enabled() function
should also be implemented by those types.
The only caller of nm_device_get_enabled() is NMPolicy:schedule_activate_check().
It is correct to skip Wi-Fi devices based on their enabled state.
Long ago before commit 1b49f94, NetworkManager did not touch the
MAC address at all. Since 0.8.2 NetworkManager would modify the
MAC address, and eventually it would reset the permanent MAC address
of the device.
This prevents a user from externally setting the MAC address via tools
like macchanger and rely on NetworkManager not to reset it to the
permanent MAC address. This is considered a security regression in
bgo#708820.
This only changed with commit 9a354cd and 1.4.0. Since then it is possible
to configure "cloned-mac-address=preserve", which instead uses the "initial"
MAC address when the device activates.
That also changed that the "initial" MAC address is the address which was
externally configured on the device as last. In other words, the
"initial" MAC address is picked up from external changes, unless it
was NetworkManager itself who configured the address when activating a
connection.
However, in absence of an explicit configuration the default for
"cloned-mac-address" is still "permanent". Meaning, the user has to
explicitly configure that NetworkManager should not touch the MAC address.
It makes sense to change the upstream default to "preserve". Although this
is a change in behavior since 0.8.2, it seems a better default.
This change has the drastic effect that all the existing connections
out there with "cloned-mac-address=$(nil)" change behavior after upgrade.
I think most users won't notice, because their devices have the permanent
address set by default anyway. I would think that there are few users
who intentionally configured "cloned-mac-address=" to have NetworkManager
restore the permanent address.
https://bugzilla.gnome.org/show_bug.cgi?id=770611
... and don't set ip6_state=IP_FAIL for ipv6.method=ignore.
The disabled state is like having an empty NMIP4Config object.
It should not result in %IP_FAIL state. Instead, we just want
to proceed and commit an empty NMIP4Config instance.
This was introduced by commit 0652d9c596,
which I think was wrong.
Likewise, for ipv6.method=ignore we also don't want to mark the
IP state as failed. Instead, we want to proceed and set IP_DONE
right away -- without commiting anything, which is a difference
to the IPv4 case.
This is especially important, because an ip4_state/ip6_state of IP_FAIL
causes nm_device_can_assume_active_connection() to return FALSE, which
means we unmanage devices at shutdown. Ony might say that it doesn't
matter so much for a device without IP configuration, but imagine a
bond with VLANs on top that only has Layer 2 configuration. This will
bring down the entire stack.
With this change, devices with IP methods disabled/ignore stay up on
exit of NetworkManager (rh#1371126). Of course, that means on restart
software devices stay unamanged due to external-down (because since
commit e1edcda, devices without IP address are also external-down).
So, this really just fixes one scenario, breaking another one.
This should be fixed with bgo#746440 by not assuming connections.
https://bugzilla.redhat.com/show_bug.cgi?id=1371126
brcmfmac and possibly other drivers don't change the MAC address
right away, but instead the result is delayed. That is problematic
because we cannot continue activation before the MAC address is
settled.
Add a hack to workaround the issue by waiting until the MAC address
changed.
The previous attempt to workaround this was less intrusive: we would
just refresh the link once and check the result. But that turns out
not to be sufficent for all cases. Now, wait and poll.
https://bugzilla.gnome.org/show_bug.cgi?id=770456https://bugzilla.redhat.com/show_bug.cgi?id=1374023
After the fix in [1], if the connection is assumed we don't update its
firewall zone. The goal of that change was to prevent NM from
interfering with the configuration done externally on devices not
created by NM.
However if there is an assumed persistent connection active on the
device NM touches the configuration in other ways, for example it
configures DHCP and manages the default route. So it seems correct to
also update the firewall zone.
OTOH, if the connection is assumed-generated there is no persistent
connection specifying a firewall zone and updating it makes no sense.
Bug [1] was about not interfering with devices unknown to NM (for
which there is no persistent connection) and so this change should not
conflict with the previous fix.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1098281https://bugzilla.redhat.com/show_bug.cgi?id=1366288
At this point we don't know if the slave has been using an assumed
connection that just vanished -- the best bet is to let the device be.
If it's meant to be unenslaved, it won't be due to an external event.
https://bugzilla.redhat.com/show_bug.cgi?id=1357738
When a software device unrealizes, we want to forget about the "user-explict"
unmanaged state. It means, that after a software device is deleted, the
"user-explict" managed flag will be cleared for that device.
It might be nice to preserve the managed-state after deletion of the device.
However, the unrealized-device only exists as long as we have a connection
for the device. That means, before this patch whether the unmanaged flag
was forgotten depends on whether the user had some connections that keep
the device alive as unrealized. That behavior was complicated, just don't
do that.
It seems some drivers return success for nm_platform_link_set_address(),
but at that point the address did not yet actually change *sigh*.
It changes a bit later, possibly after setting the device up.
Add a workaround to retry reading the MAC address when platform indicates
success but the address still differs at first.
https://bugzilla.gnome.org/show_bug.cgi?id=770456
When activating a connection, it may fail with nmcli reporting:
$ nmcli connection up id "Wired Connection 1"
Error: Connection activation failed: Active connection removed before it was initialized
This should be easily reproducible by having a connection "Wired Connection 1" with
cloned-mac-address set to random. When the connection is already active on a device,
re-activating with
$ nmcli connection up id "Wired Connection 1"
fails.
We first create a queued-activation and tear down the existing
connection:
device (enp0s25): state change: deactivating -> disconnected (reason 'new-activation')
Shortly after we see:
device[0x557d02cdb0c0] (enp0s25): set-hw-addr: setting MAC address to 'AA:BB:CC:DD:EE:FF' (reset, deactivate)...
device[0x557d02cdb0c0] (enp0s25): taking down device
later, we get:
device (enp0s25): link disconnected
device[0x557d02cdb0c0] (enp0s25): queued state change to unavailable due to carrier-changed (id 17290)
in the meantime, the queued activation request starts:
device (enp0s25): Activation: starting connection 'my-wired' (ca058ec5-8a47-4e1e-b38e-962b71c4699e)
but the device already transitions to unavailable
device[0x557d02cdb0c0] (enp0s25): running queued state change to unavailable (id 17290)
device (enp0s25): state change: disconnected -> unavailable (reason 'carrier-changed') [30 20 40]
which kills the new activation request:
active-connection[0x557d02c10e40]: set state deactivated (was unknown)
Just delay a carrier-lost handling if we have any queued activation
requests.
(cherry picked from commit d4e9b30320)
When a assumed software device is brought down externally, it becomes
UNMANAGED_EXTERNAL_DOWN and its state goes from ACTIVATED directly to
UNMANAGED. In such case, we shouldn't flush the IP configuration
(addresses and routes) present on the device.
To fix this, clean up the device with CLEANUP_TYPE_KEEP and modify
nm_device_cleanup() not to flush addresses and devices with such flag.
https://bugzilla.redhat.com/show_bug.cgi?id=1363995
(cherry picked from commit 45cd3302dc)
- don't include "nm-default.h" in header files. Every source file must
include as first header "nm-default.h", thus our headers get the
default include already implicitly.
- we don't support compiling NetworkManager itself with a C++ compiler. Remove
G_BEGIN_DECLS/G_END_DECLS from internal headers. We do however support
users of libnm to use C++, thus they stay in public headers.
(cherry picked from commit f19aff8909)
Instead of updating the device-statistic counters only periodically as
we refresh the link, update them on every link-changed event from
platform.
That means, also for devices that have RefreshRateMs at zero, the values
will be updated at random times when the link information changes.
The difference is, that previously the counters would be zero unless
RefreshRateMs was set. Now, they have some (probably stale) values
which however are not guaranteed to be kept up-to-date.
Also, now we refresh more often then promised by RefreshRateMs. But the API
technically doesn't specify that, so if we find there is a problem with
this, we may revert it later.
Originally, "nm-device-statistics.c" contained code to fetch the device
counters via netlink. As now the netlink part is handled by NMPlatform,
the code can be simplified by merging it back to NMDevice.
Add statistics interface to all device instances. When active, the
properties of this interface are refreshed whenever there is network
activity for the device.
Activation is performed by changing RefreshRateMs property. If set to
zero, the interface is deactivated. If set to other value, the rest of
the interface properties are refreshed whenever the related network
metric changes, being RefreshRateMs the minimum time between property
changes, in milliseconds.
Unfortunately teamd doesn't have an asynchronous way to notify a
change in the actual configuration, so when a port is enslaved or
released we wait some time for the changes to take effect and read the
configuration again.
https://bugzilla.redhat.com/show_bug.cgi?id=1310435
Request the actual configuration when reading it from teamd. The
actual configuration, differently from the normal one, doesn't contain
non-active team ports.
enables (back) matching against 802-3-ethernet.mac-address and
802-3-ethenet.mac-address-blacklist connection parameters
for MAC addresses belonging to virtual devices too.
On every start of NetworkManager I'd see a warning message:
modem-broadband[cdc-wdm0]: failed to retrieve SIM object: No SIM object available
Apparently, to warn about this is too alarming.
Commit f85941ee91 ("device: don't try to generate ipv6ll address for
disconnected devices") disabled the generation of IPv6 link-local
addresses for disconnected devices to fix a crash. However that broke
the following:
$ ip a f dev eth0
$ systemctl start NetworkManager
$ nmcli d
DEVICE TYPE STATE CONNECTION
eth0 ethernet disconnected eth0
$ ip a a dev eth0 2001::42/64
$ ip a show eth0
4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:52:00:61:32:81 brd ff:ff:ff:ff:ff:ff
inet6 2001::42/64 scope global
valid_lft forever preferred_lft forever
(no link-local address)
Instead, enable the generation of a link-local address even if the
device is disconnected and fix nm_device_get_ip_iface_identifier() to
not require a connection if @ignore_token is set.
Fixes: f85941ee91