On Ubuntu 20.10, we build against ModemManager 1.14.0 and get a compiler warning:
../src/devices/wwan/nm-modem-broadband.c: In function 'try_create_connect_properties':
../src/devices/wwan/nm-modem-broadband.c:492:2: error: 'MMModemCapabilityDeprecated' is deprecated [-Werror=deprecated-declarations]
492 | if (MODEM_CAPS_3GPP (ctx->caps)) {
| ^~
Suppress it.
An alternative would be to drop the flag entirely. It seems the flag
was never used (and never will be used). But if that's true, there is
little harm done checking it. If it's not true, we better keep checking
for older versions.
0cd76bf1c4
There are some APs that require a DHCP transaction before allowing
other traffic. This is meant to improve security by preventing the use
of static addresses. Currently we don't renew DHCP after roaming to a
new AP and this can lead to broken connectivity with APs that
implement the check described above. Also, even if unlikely, the new
AP could be in a different layer 3 network and so the old address
could be no longer valid.
Renew dynamic IP configuration after we detect the supplicant decided
to roam to a new AP. Note that we only trigger a DHCP client restart;
the DHCP client already implements the logic to renew the previous
address and fall back to a full request in case of NAK or timeout.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/449
Code like "get_setting_default_uint (s_bridge, NM_SETTING_BRIDGE_FORWARD_DELAY)" looks
up the default value of the GObject property. That default value is
known at build type. Looking it up is an unnecessary overhead, for
something that is already known.
Also, the code isn't generic (meaning, it doesn't iterate of a set of
properties names and treats them without explicitly naming each
property). If we already name the property for which we want the default
value, we can just as well name the default value.
Additionally, add an assertion that what we would look up matches
to what we think is the default.
For simple matches like match.interface-name, match.driver, and
match.path, arguably what we had was fine. There each element
(like "eth*") is a wildcard for a single name (like "eth1").
However, for match.kernel-command-line, the elements match individual
command line options, so we should have more flexibility of whether
a parameter is optional or mandatory. Extend the syntax for that.
- the elements can now be prefixed by either '|' or '&'. This makes
optional or mandatory elements, respectively. The entire match
evaluates to true if all mandatory elements match (if any) and
at least one of the optional elements (if any).
As before, if neither '|' nor '&' is specified, then the element
is optional (that means, "foo" is the same as "|foo").
- the exclamation mark is still used to invert the match. If used
alone (like "!foo") it is a shortcut for defining a mandatory match
("&!foo").
- the backslash can now be used to escape the special characters
above. Basically, the special characters ('|', '&', '!') are
stripped from the start of the element. If what is left afterwards
is a backslash, it also gets stripped and the remainder is the
pattern. For example, "\\&foo" has the pattern "&foo" where
'&' is no longer treated specially. This special handling of
the backslash is only done at the beginning of the element (after
the optional special characters). The remaining string is part
of the pattern, where backslashes might have their own meaning.
This change is mostly backward compatible, except for existing matches
that started with one of the special characters '|', '&', '!', and '\\'.
The 7th field of:
ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}:[:[<mtu>][:<macaddr>]]
specifies which kind of autoconfiguration to do. 'none' and 'off' mean
static addresses.
The old network module of dracut used to leave kernel IPv6
autoconfiguration enabled when IPv4 static addresses were
configured. With NM, this corresponds to enabling IPv6 auto method.
https://bugzilla.redhat.com/show_bug.cgi?id=1848943
When the initrd generator creates a connection with IPv6 method
'ignore', the kernel will do IPv6 autoconfiguration on the
interface. However, it is preferable to let NetworkManager configure
the interface directly instead of relying on kernel. Therefore, change
the IPv6 method to 'auto'. Note that we still set ipv6.may-fail to
'yes' so that a failure during IPv6 autoconfiguration doesn't bring
down the interface.
The kernel command line supports escaping and quoting (at least,
according to systemd's parser, which is our example to follow).
Use nm_utils_strsplit_quoted() which supports that.
Iterating hash tables gives an undefined order. Often we want to have
a stable order, for example when printing the content of a hash or
when converting it to a "a{sv}" variant.
How to achieve that best? I think we should only iterate the hash once,
and not require additional lookups. nm_utils_named_values_from_strdict()
achieves that by returning the key and the value together. Also, often
we only need the list for a short time, so we can avoid heap allocating
the list, if it is short enough. This works by allowing the caller to
provide a pre-allocated buffer (usually on the stack) and only as fallback
allocate a new list.
The commit breaks many nmstate CI tests. It also breaks the
autoconnect-slaves functionality: if the master gets reactivated and
the slave was active, the slave is not reconnected.
A different solution is needed for the original issue.
This reverts commit 024e983c8e.
Add a new "path" property to the match setting, which can be used to
restrict a connection to devices with a given hardware path. The new
property is a list of patterns that are matched against the ID_PATH
udev property of devices.
ID_PATH represents the topological persistent path of a device and
typically contains a subsystem string (pci, usb, platform, etc.) and a
subsystem-specific identifier. Some examples of paths are:
pci-0000:00:02.0
pci-0000:00:14.0-usb-0:5:1.0
platform-1c40000.ethernet
systemd-networkd also has a "Path=" option to match a device by udev
ID_PATH.
Do what systemd does with sd_lldp_neighbor_get_chassis_id_as_string()
and sd_lldp_neighbor_get_port_id_as_string(). Maybe we should use the
systemd functions directly, however that is not done because the way
how we convert the values to string is part of our stable API. Let's not
rely on systemd for that.
Also, support SD_LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS and SD_LLDP_PORT_SUBTYPE_NETWORK_ADDRESS
types. Use the same formatting scheme as systemd ([1]) and lldpd ([2]).
[1] a07e962549/src/libsystemd-network/lldp-neighbor.c (L422)
[2] d21599d2e6/src/lib/atoms/chassis.c (L125)
Also, in case we don't support the type or the type contains unexpected
data, fallback to still expose the LLDP neighbor, and convert the value
to a hex string (like systemd does). This means, lldp_neighbor_new()
in practice can no longer fail and the error handling for that can be
dropped.
There is one tiny problem: now as fallback we expose the
chassis-id/port-id as hex string. That means, if we in the future
recognize a new type, we will have to change API for those types.
The alternative would be to either hide the neighbor completely from the
D-Bus API (as previously done), or not expose the hex strings on D-Bus.
Neither seems very attractive, so expose the value (and reserve the
right to change API in the future).
For the ID of LLDP neighbors follow what systemd does (w.r.t. what it
consideres equality of two neighbors).
Note that previously we did almost the same thing. Except, we compared
priv->chassis_id and priv->port_id, but these values are string
representations of the original (binary value). Don't use the pretty
strings as ID but the original binary value.
An invalid destination address doesn't need to break the LLDL neighbor entirely.
In fact, systemd will already filter out such addresses. So in practice,
the neighbor always has a valid destination address.
There is thus no need to parse it already during lldp_neighbor_new().
When the instance is not running (after creation or after stop), there
is no need to keep the GHashTable around.
Create it when needed (during start) and clear it during stop. This
makes it slightly cheaper to keep a NMLldpListener instance around,
if it's currently not running.
NMDevice already keeps the NMLldpListener around, even after stopping
it. It's not clear whether the instance will be started again, so also
clear the GHashTable. Also, one effect is that if you initially were in
a network with many LLDP neibors, after stop and start, the GHashTable
now gets recreated and may not need to allocate a large internal array
as before.
We already rate limit change events by two seconds. When we notice
that something changed, we call data_changed_schedule().
Previously, that would immediately issue the change notification,
if ratelimiting currently was not in effect. That means, if we happen
go receive two LLDP neighbor events in short succession, then the
first one will trigger the change notification right away, while
the second will be rate limited.
Avoid that by always issue scheduling the change notification in
the background. And if we currently are not rate limited, with
an idle handler with low priority.
This changes the order to what the code did previously, before switching
from GVariantDict to GVariantBuilder. But it changes the actually
serialized order in the variant.