Some device types might want to use a custom method to set an IPv6
link-local address. For example, with PPP the interface identifier is
announced by the server via IPV6CP.
As almost always, there is a point in keeping IPv4 and IPv6 implementations
similar. Behave different where there is an actual difference, at the bottom
of the stack.
Technically, g_warn_if_reached() may not be an assertion, according to
glib. However, there is G_DEBUG=fatal-warnings and we want to run with
that.
So this is an assertion to us. Also, logging to stderr/stdout is not a
useful thing to the daemon. Don't do this. Especially, since it depends
on user provided (untrusted) input.
Optimally we want stateless, pure code. Obviously, NMDhcpClient needs to
keep state to know what it's doing. However, we should well encapsulate
the state inside NMDhcpClient, and only accept events/notifications that
mutate the internal state according to certain rules.
Having a function public set_state(self, new_state) means that other
components (subclasses of NMDhcpClient) can directly mangle the state.
That means, you no longer need to only reason about the internal state
of NMDhcpClient (and the events/notifications/state-changes that it
implements). You also need to reason that other components take part of
maintaining that internal state.
Rename nm_dhcp_client_set_state() to nm_dhcp_client_notify(). Also, add
a new enum NMDhcpClientEventType with notification/event types.
In practice, this is only renaming. But naming is important, because it
suggests the reader how to think about the code.
The "noop" state is almost unused, however, nm_dhcp_set_state()
has a check "if (new_state >= NM_DHCP_STATE_TIMEOUT)", so the order
of the NOOP state matters.
Fix that by reordering.
Also, just return right away from NOOP.
NMDhcpState is very tied to events from dhclient. But most of these
states we don't care about, and NMDhcpClient definitely should abstract
and hide them.
We should repurpose NMDhcpState to simpler state. For that, first drop
the state from nm_dhcp_client_handle_event().
This is only the first step (which arguably makes the code more
complicated, because reason_to_state() gets spread out and the logic
happens more than once). That will be addressed next.
- return early to avoid nested block.
- use NM_STR_HAS_PREFIX() over g_str_has_prefix(), because that
can be inlined and only accepts a C literal as prefix argument.
- the code comment was unclear/wrong. If something comes from an environment
variables it is *NOT* UTF-8 safe. Also, we convert all non-ASCII characters,
not only non UTF-8 characters.
- as we already convert the string to ASCII, the check whether it's UTF-8
is bogus.
- using GString is unnecessary.
- use NM_IN_STRSET_ASCII_CASE().
- don't use else block after we return.
- don't accept the "iface" argument just for logging. The caller
can do the logging, if they wish.
g_bytes_ref() does not accept NULL. But doing so can be convenient,
add a helper for that.
Note that g_bytes_unref() does accept NULL, so there is no corresponding
helper.
Log messages when invalid DHCP options are found. For example:
<info> dhcp4 (eth0): error parsing DHCP option 6 (domain_name_servers): address 0.0.0.0 is ignored
<info> dhcp4 (eth0): error parsing DHCP option 12 (host_name): '.example.com' is not a valid DNS domain
<info> dhcp4 (eth0): error parsing DHCP option 26 (interface_mtu): value 60 is smaller than 68
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1225
A virtual infiniband profile (with p-key>=0) can also contain a
"connection.interface-name". But it is required to match the
f"{parent}.{p-key}" format.
However, such a profile can also set "mac_address" instead of "parent".
In that case, the validation code was crashing.
nmcli connection add type infiniband \
infiniband.p-key 6 \
infiniband.mac-address 52:54:00:86:f4:eb:aa:aa:aa:aa:52:54:00:86:f4:eb:aa:aa:aa:aa \
connection.interface-name aaaa
The crash was introduced by commit 99d898cf1f ('libnm: rework caching
of virtual-iface-name for infiniband setting'). Previously, it would not
have crashed, because we just called
g_strdup_printf("%s.%04x", priv->parent, priv->p_key)
with a NULL string. It would still not have validated the connection
and passing NULL as string to printf is wrong. But in practice, it
would have worked mostly fine for users.
Fixes: 99d898cf1f ('libnm: rework caching of virtual-iface-name for infiniband setting')
clang 3.4.2-9.el7 does not like this:
$ clang -DHAVE_CONFIG_H -I. -I.. -I../src/libnm-core-public -I./src/libnm-core-public -I../src/libnm-client-public -I./src/libnm-client-public -pthread -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_40 -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_40 -Wall -Werror -Wextra -Wdeclaration-after-statement -Wfloat-equal -Wformat-nonliteral -Wformat-security -Wimplicit-function-declaration -Winit-self -Wmissing-declarations -Wmissing-include-dirs -Wmissing-prototypes -Wpointer-arith -Wshadow -Wstrict-prototypes -Wundef -Wvla -Wno-duplicate-decl-specifier -Wno-format-y2k -Wno-missing-field-initializers -Wno-sign-compare -Wno-tautological-constant-out-of-range-compare -Wno-unknown-pragmas -Wno-unused-parameter -Qunused-arguments -Wunknown-warning-option -Wtypedef-redefinition -Warray-bounds -Wparentheses-equality -Wunused-value -Wimplicit-fallthrough -fno-strict-aliasing -fdata-sections -ffunction-sections -Wl,--gc-sections -g -O2 -MT examples/C/glib/examples_C_glib_add_connection_libnm-add-connection-libnm.o -MD -MP -MF examples/C/glib/.deps/examples_C_glib_add_connection_libnm-add-connection-libnm.Tpo -c -o examples/C/glib/examples_C_glib_add_connection_libnm-add-connection-libnm.o `test -f 'examples/C/glib/add-connection-libnm.c' || echo '../'`examples/C/glib/add-connection-libnm.c
...
../src/libnm-client-public/nm-client.h:149:31: error: redefinition of typedef 'NMClient' is a C11 feature [-Werror,-Wtypedef-redefinition]
typedef struct _NMClient NMClient;
^
Our code base is C11 internally (actually "-std=gnu11"), but this problem
happens when we build the example. The warning is actually correct, because
our public headers should be more liberal (and possibly be C99 or even C89,
this is undefined).
Fixes: 649314ddaa ('libnm: replace nm-types.h by defining the types in respective headers')
We no longer have "nm-types.h", which forward declares most relevant
typedefs. We also don't ensure that each header includes all the
headers that it has a dependency (instead, we rely on the user to
include "NetworkManager.h", which does the right thing).
The "right thing" depends on doing doing it in the right order.
Reorder the includes.
We want to warn the user if they're connecting to an insecure network:
$ nmcli d wifi
IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS SECURITY
BA:00:6A:3C:C2:09 Secured Network Infra 2 54 Mbit/s 100 ▂▄▆█ WPA3
FA:7C:46:CC:9F:BE Ye Olde Wlan Infra 1 54 Mbit/s 100 ▂▄▆█ WEP
$ nmcli d wifi connect 'Ye Olde Wlan'
Warning: WEP encryption is known to be insecure.
...
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1224
audit_encode_nv_string() is documented that it might fail. Handle
the error.
Also, the returned string was allocated with malloc(). We must free
that with free()/nm_auto_free, not g_free()/gs_free.
Try to workaround a coverity warning:
30. NetworkManager-1.39.3/src/core/vpn/nm-vpn-connection.c:2000:
overrun-buffer-val: Overrunning array "address.ax.address_ptr" of 1
bytes by passing it to a function which accesses it at byte offset 3.
Currently nm_setting_bond_get_option_normalized() and
nm_setting_bond_get_option_or_default() are identical functions. As the
first one is exposed as public API and has a better name, let's drop the
second one.
tun/tap connections can be created using a command such as:
$ nmcli connection add type tun ifname tun0 mode tap owner 1000
They appear in nmcli connection as TYPE "tun".
This patch adds the ability to activate and deactivate this type of
connection using nmtui.
Each connection of TYPE "tun" appears as:
TUN/TAP (<ifname>)
* <connection-name>
Example:
TUN/TAP (tap0)
* bridge-slave-tap0
TUN/TAP (tap1)
bridge-slave-tap1
IPv6 temporary addresses are configured by kernel, with the
"ipv6.ip6-privacy" setting ("use_tempaddr" sysctl) and the
IFA_F_MANAGETEMPADDR flag.
As such, the idea was that during reapply we would not remove them.
However, that is wrong.
The only case when we want to keep those addresses, is if during reapply
we are going to configure the same primary address (with mngtmpaddr
flag) again. Otherwise, theses addresses must always go away.
This is quite serious. This not only affects Reapply. Also during disconnect
we clear IP configuration via l3cfg.
Have an ethernet profile active with "ipv6.ip6-privacy". Unplug
the cable, the device disconnects but the temporary IPv6 address is not
cleared. As such, nm_device_generate_connection() will now generate
an external profile (with "ipv6.method=disabled" and no manual IP addresses).
The result is, that the device cannot properly autoconnect again,
once you replug the cable.
This is serious for disconnect. But I could not actually reproduce the
problem using reapply. That is, because during reapply we usually
toggle ipv6_disable sysctl, which drops all IPv6 addresses. I still
went through the effort of trying to preserve addresses that we still
want to have, because I am not sure whether there are cases where we
don't toggle ipv6_disable. Also, doing ipv6_disable during reapply is
bad anyway, and we might want to avoid that in the future.
Fixes: 58287cbcc0 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
All our sources should include one of the "nm-default*.h" headers
first. That one drags in <config.h>, which must be included first
and a few other basics.
Which is the right "nm-default*.h" header depends on the component. In
case of "nm-daemon-helper.c", it's "libnm-std-aux/nm-default-std.h".