For an IPv4 subnet mask we expect that all the leading bits are set (no
"holes"). But _nm_utils_ip4_netmask_to_prefix() does not enforce that,
and tries to make the best of it.
In face of a netmask with holes, normalize the mask.
We have two variants of the function: nm_utils_ip4_netmask_to_prefix()
and _nm_utils_ip4_netmask_to_prefix(). The former only exists because it
is public API in libnm. Internally, only use the latter.
nm_utils_ip4_netmask_to_prefix() and nm_utils_ip4_prefix_to_netmask()
are public API in libnm.
We thus already have an internal implementation _nm_utils_ip4_prefix_to_netmask(),
for non-libnm users. Internally, we should never use the libnm variant.
For consistency and so that we have the helper available in
libnm-glib-aux, add _nm_utils_ip4_netmask_to_prefix().
There was already an nm_assert() assertion. Upgrade this
to a g_return_val_if_fail(). This function is public API,
so this is potentially an API break. But it should highlight
a bug in the caller.
Apt is run for each package separately and errors are ignored. This is
not great -- it's slow and ignores errors. Therefore we sometimes end
up without packages we need.
Let's tolerate errors only for packages that we are know can fail to
install safely.
In practice, the profile probably validates, so all the
attribute names are well-known. There is thus no attribute
name that has "lock-" in the middle of the string.
Still, fix it. We want to match only at the begin of the
name.
In a logfile, the "is starting" message is an interesting point
that indicates when NetworkManager is starting. Include
also the boot-id in the log, so that we can know whether this
was a restart from the same boot.
Also drop the "for the first time" part.
<info> [1656057181.8920] NetworkManager (version 1.39.7) is starting... (after a restart, asserts:10000, boot:486b1052-4bf8-48af-8f15-f3e85c3321f6)
Setting `NM_SET_OUT(out_normalized, !is_normalized)` is correct, but looks
odd and required a long code comment.
Try to write the same code differently, I think it is easier to
read and requires less comment to explain.
- replace "s_flags" field by explicit boolean fields.
- "s_msg_peek" now is simplified. Previously, we would default
to peek, unless the user caller nl_socket_disable_msg_peek()
or set nl_socket_set_msg_buf_size(). Simplify that. We now
default to peek, unless NL_SOCKET_FLAGS_DISABLE_MSG_PEEK is set.
We have no callers that call nl_socket_set_msg_buf_size(),
so we can simplify that logic and just enable peeking by default.
- keep "s_auto_ack" field, although it is always TRUE and there
is no API to toggle that. However, it is kept as a self-documenting
thing, so we would know the relevant places where auto-ack matters.
- drop nl_socket_disable_msg_peek(). We have no caller of this function
and we can set peeking in nl_socket_new(). We also don't need to
change it after creation of the socket.
The real purpose is that we set the socket options before bind().
For that, we need to be able to specify the flag during nl_socket_new().
Another reason is that these are common questions to ponder while
creating a netlink socket. There shouldn't be several setter functions,
just specify the flag right away. These parameters are not going to
change afterwards (at least, we don't need/use that and we don't have
API for that either).
We will need this, for getting nl_pktinfo control messages
that contain the extended destination group number.
Also, drop NL_SOCK_PASSCRED. It was only used to not iterate over the
control messages, but doing that should be cheap.
There really is no need for two(!) heap allocations while parsing
the netlink message. We already have it in the buffer. Just use it.
Note that netlink attributes need to be aligned to 4 bytes. But
nlmsg_next() already ensures that, so not even for alignment purpose we
need to clone the message.
Create a new "struct nl_msg_lite" that can hold pointers to everything
we need.
We almost always do the wrong thing in interactive add:
The software devices generally require an interactive name, but we don't
insist of asking for them; treating them as optional:
$ nmcli -a c add type dummy
There is 1 optional setting for General settings.
Do you want to provide it? (yes/no) [yes]
For some interface types (bridges, bonds, ...) we make up a name, presumably
for historical reasons. But we don't give the user an option to modify
them:
$ nmcli -a c add type bridge
<not asking for interface name at all>
There are 9 optional settings for Bridge device.
Do you want to provide them? (yes/no) [yes]
This fixes the above use cases -- still set the default, but be sure to
ask:
$ nmcli -a c add type dummy
Interface name:
$ nmcli -a c add type bridge
Interface name [nm-bridge1]:
Beautiful.
Do the same bookkeeping as would happen upon setting the "type" option
when the connection has a connection.type set upon its addition.
Otherwise the --ask mode is sad:
$ nmcli --ask c add connection.type team
** nm:ERROR:src/nmcli/connections.c:5648:connection_get_base_meta_setting_type: assertion failed: (base_setting)
Bail out! nm:ERROR:src/nmcli/connections.c:5648:connection_get_base_meta_setting_type: assertion failed: (base_setting)
Aborted (core dumped)
After the connection's type is set, some bookkeeping is necessary for
the interactive (--ask) mode: appropriate setting need to be added and
options enabled.
Currently it happens in an option setter; which runs when the "type"
options is present on the command line, or the value is set in a
response to interactive mode:
$ nmcli --ask c add type team
$ nmcli --ask c add
Connection type: team
But not when the property is set directly:
$ nmcli --ask c add connection.type team
** nm:ERROR:src/nmcli/connections.c:5648:connection_get_base_meta_setting_type: assertion failed: (base_setting)
Bail out! nm:ERROR:src/nmcli/connections.c:5648:connection_get_base_meta_setting_type: assertion failed: (base_setting)
Aborted (core dumped)
This doesn't fix the issue -- a followup commit (hopefully) will.
For new connections, this ensures the value in square brackets on
interactive add are always correct.
Apart from that, this allows us to initialize some non-default values
before asking (such as making up an interface name for some software
devices), and inform the user about what we picked:
Interface name [nm-bridge]:
This is slightly annoying:
$ nmcli -a c add type ethernet
There is 1 optional setting for General settings.
No point in asking if there's just one option. Just ask right away:
$ nmcli -a c add type ethernet
Interface name:
The interactive add is not too enthusiastic about not providing a value
in a list.
That is before on getting an empty line in ask_option() we take a
shortcut instead of dispatching to set_option(). That way we skip
setting the PROPERTY_INF_FLAG_DISABLED flag, causing the option to
be included in questionnaire_one_optional()'s info list.
There's no reason to avoid calling set_option() if we don't get a value;
set_option() handles NULL value just fine.
$ nmcli -a c add
Connection type: dummy
There is 1 optional setting for General settings.
Do you want to provide it? (yes/no) [yes]
Interface name [*]: lala
There are 2 optional settings for IPv4 protocol.
Do you want to provide them? (yes/no) [yes]
You can specify this option more than once. Press <Enter> when you're done.
IPv4 address (IP[/plen]) [none]:
You can specify this option more than once. Press <Enter> when you're done.
IPv4 address (IP[/plen]) [none]:
You can specify this option more than once. Press <Enter> when you're done.
IPv4 address (IP[/plen]) [none]:
...
Whether we use a socket blockingly or non-blocking is usually determined
upfront and does not change. Make it a parameter of nl_socket_new().
Also, it saves an additional syscall.
This is not good:
$ nmcli device delete nm-bond
Segmentation fault (core dumped)
Fixes: 5f9d2927ed ("nmcli/devices: use GPtrArray from get_device_list() directly")