Commit graph

438 commits

Author SHA1 Message Date
Thomas Haller
dc98ab807c
platform: include "linux-headers" via "libnm-std-aux/nm-linux-compat.h"
We have our own copy of linux kernel headers, and we must never
directly include the corresponding versions from the system.

Avoid that, by only including the clones via "libnm-std-aux/nm-linux-compat.h"
and by including the compat wrapper header before other system headers.
2022-07-26 12:28:04 +02:00
Thomas Haller
b3f60d891f
platform: assert for success genlmsg_put() in _nl802154_alloc_msg() 2022-07-26 12:28:04 +02:00
Thomas Haller
9c3e0846ee
platform/trivial: add blank line after variable declaration in NLA_PUT_TYPE() 2022-07-26 12:28:04 +02:00
Wen Liang
bd84ae4dc5 platform: add the a_no_auto_noprefixroute flag
`nm_platform_ip_address_sync()` likes to add IFA_F_NOPREFIXROUTE flag
for all addresses, regardless of `a_ifi_flags` property. By setting this
boolean, that automatism can be suppressed, and the noprefixroute flag
does not get added automatically.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1307
2022-07-21 09:09:03 -04:00
Thomas Haller
2fb2a83090
platform: fix compile error in event_seq_check()
Some compiler versions don't like this. Workaround.

  src/libnm-platform/nm-linux-platform.c: In function event_seq_check:
  src/libnm-platform/nm-linux-platform.c:7254:1: error: label at end of compound statement
   out:
   ^~~

Fixes: 3d4906a3da ('platform: add genl socket support for events and genl family')
2022-07-20 21:07:01 +02:00
Thomas Haller
c391162a81
platform: print genl family ID in hex format
That seems common. It's also done by genl-ctrl-list and
iproute2's genl tool.

Also, use avoid the leading zeros (0x1c instead of 0x001c).
iproute2's genl tool does the former, libnl3's genl-ctrl-list
does the latter.
2022-07-20 14:42:25 +02:00
Thomas Haller
e9f6e0abe1
platform: try harder to get the genl family ID by getting it synchronously
We now cache the family ID for generic netlink protocols. However,
when we for example create a wireguard interface, the kernel module
might just get autoloaded. At this point, we didn't know the family ID
yet.

We already made an effort, that if the family ID is unknown during
nm_platform_genl_get_family_id(), we would try to poll the genl socket
in the hope there is a relevant event there. However, polling the socket
also means to potentially emit all signals for any change that happen.
We don't want that, if we currently are already polling the socket.

Instead, fallback to synchronously get the family ID.

  $ sudo rmmod wireguard \
    ./tools/run-nm-test.sh -m src/core/platform/tests/test-link-linux -p /link/software/detect/wireguard/1/external

Fixes: 3d4906a3da ('platform: add genl socket support for events and genl family')
2022-07-20 14:33:51 +02:00
Thomas Haller
1a0c8772b0
platform: add NMPlatformMptcpAddr object
An NMPObject is hashable, can be compared and printed. That is useful.
Make an NMPObject for MPTCP addresses. It will hold the content of
MPTCP_PM_ATTR_ADDR netlink attribute. But like other NMPObject types it
will also be used to represent the data as NetworkManager tracks it.
2022-07-20 10:25:47 +02:00
Thomas Haller
be4b775585
platform: avoid logging plain pointer values in "nmp-object.c" 2022-07-20 10:25:46 +02:00
Thomas Haller
543a22af0a
platform: drop unnecessary cmd_plobj_id_copy implementations
The default implementation just uses memcpy() of the public part. That
is just what we want. No need to implement those functions.
2022-07-20 10:25:46 +02:00
Thomas Haller
a242d41cc0
platform: improve nmp_object_stackinit_id() for types that don't implement cmd_plobj_id_copy()
An object type that doesn't implement cmd_plobj_id_copy(), either:

- implements cmd_obj_copy(), but then we cannot copy the ID only
  to a stack instance, because that cannot track ownership.
  This is a bug in the caller. We cannot use stackinit for an
  object of a type that is not a plain old data (in C++ terms).

- fallback to plain memcpy(). That is in line with nmp_object_clone().
  and nmp_object_copy().
2022-07-20 10:24:45 +02:00
Thomas Haller
52c8ee2c9d
platform: drop detecting address scope in _nl_msg_new_address()
All callers explicitly set a scope, like they should. Drop guessing
the scope. Also, use the proper integer type.
2022-07-20 10:23:05 +02:00
Thomas Haller
45ca7dfaf3
platform/netlink: add NLA_S32 enum value for attribute type 2022-07-20 10:23:05 +02:00
Thomas Haller
19f14dbf37
platform/netlink: adjust integer types in netlink API
- use proper integer types. A netlink message cannot be as large as
  size_t, because the length is tracked in an uint32_t. Use the
  right types.

- fields like "nlmsg_type" or "nlmsg_flags" are uint16_t. Use the
  right types.

- note that nlmsg_size() still returns and accepts "int". Maybe
  the should be adjusted too, but we use macros from kernel headers,
  which also use int. Even if that is not the type of the length on
  the binary protocol. So some of these functions still use int, to
  be closer and compatible with <linux/netlink.h>.
2022-07-19 12:36:57 +02:00
Thomas Haller
9c34998281
platform: use new platform API to get genl family id for nl802154/wpan 2022-07-19 12:36:57 +02:00
Thomas Haller
36e6ac5450
platform: use new platform API to get genl family id for nl80211/Wi-Fi 2022-07-19 12:36:57 +02:00
Thomas Haller
f40dcd65f7
platform: use new platform API to get genl family id for wireguard 2022-07-19 12:36:57 +02:00
Thomas Haller
3d4906a3da
platform: add genl socket support for events and genl family
For generic netlink, the family-id is important. It changes when
loading/unloading a module, so we should not cache it indefinitely.
To get this right, takes some effort. For "nl80211", "nl802154"
and "wireguard", we only cache the family ID in relation to an
interface. If the module gets unloaded, the family ID also becomes
irrelevant and we need to re-fetch it the next time.

For generic families like "mptcp_pm" or "ethtool", they are commonly not
kernel modules and cannot be unloaded. So caching them would be
(probably) fine.

Still. Some generic netlink families emit notifications, and it will
be interesting to be able to handle them. Since that will be useful later,
start by doing something simple: let the generic netlink family also be
cached this way. Generic netlink will send notifications when a family gets
added/deleted, and we can use that to reliably cache the family ID.

We only care about a well-known set of generic families. Unlike libnl
(which has "struct genl_family" object to handle any family), we can hard
code the few we care about (NMPGenlFamilyType).

This adds the necessary infrastructure of NMLinuxPlatform to listen to
events on the generic netlink socket.
2022-07-19 12:36:57 +02:00
Thomas Haller
355331b779
platform: make FOR_EACH_DELAYED_ACTION() robust against integer overflow
Currently there is no problem. However, DelayedActionType is a packed
enum, and if we add a few more enum values, it might happen that
DELAYED_ACTION_TYPE_MAX is 0x8000 and DelayedActionType effectively
uint16_t.

When that happens, the code would become an infinite loop, because
0x8000 is not larger than DELAYED_ACTION_TYPE_MAX, but `<<= 1`
shifts out the bit, making it zero.

Avoid that.
2022-07-19 12:36:57 +02:00
Thomas Haller
d83bd8c6a0
platform: rename DELAYED_ACTION_TYPE_REFRESH_ALL_* enums to "all-rtnl"
We'll also have generic netlink things. Rename.
2022-07-19 12:36:56 +02:00
Thomas Haller
8d42b5c52a
platform: add delayed_action_schedule_refresh_all() helper and avoid refreshing tc cache
If nm_platform_get_cache_tc() is disabled, there is no need to refresh
it. Filter those flags out.

Also, don't duplicate the code and add a helper function
delayed_action_schedule_refresh_all().
2022-07-19 12:36:56 +02:00
Thomas Haller
a27e9b21cf
platform: rename rtnetlink specific enum values to be clearly about rtnl
We will have similar names which are about generic netlink. Rename to be
clear.
2022-07-19 12:36:56 +02:00
Thomas Haller
6ff6c1dfc1
platform: tighter pack structs and enums
Reorder fields in DelayedActionWaitForNlResponseData, so that
the struct size is optimal due to the alignment constraints.

Also, when we remember enum values and embed them somewhere, it's nice
if they only take the space actually needed. _nm_packed solves that.
2022-07-19 12:36:56 +02:00
Thomas Haller
baecadbe98
platform: rename RefreshAllInfo.addr_family to "addr_family_for_dump"
The term "addr_family" is used very frequently, and it usually is an
auto variable or a function parameter.

It is interesting to search where this field is used. So rename to give
it a unique (and better fitting) name.

While at it, use gint8 to encode the addr_family. It's always
sufficient, and this reduces the size of RefreshAllInfo from 8 bytes
to two.
2022-07-19 12:36:56 +02:00
Thomas Haller
3b58404712
platform: add NMPGenlFamilyType enum for generic netlink types
The genl types that we care about are well known. Add an enum
for them, so we can do a lookup by index.

To kernel, the corresponding names (like "wireguard") are also well
known. However, the family-id, that we need when using genl are
allocated dynamically. So we need to lookup the family-id, and by having
an enum for the genl type, we can do so generically.
2022-07-19 12:33:50 +02:00
Thomas Haller
9ef02ef7d0
platform/netlink: ensure padding is zero in _nest_end()
nla_reserve() also ensures that the padding is zero, and only the
padding. Thus, when we call nla_reserve(), we need to zero the padding
ourselves.
2022-07-19 12:33:49 +02:00
Thomas Haller
d8a4b3bec2
all: reformat with clang-format (clang-tools-extra-14.0.0-1.fc36) and update gitlab-ci to f36 2022-07-06 11:06:53 +02:00
Thomas Haller
5245fc6c75
platform: rename nmp_lookup_init_object() to nmp_lookup_init_object_by_ifindex()
In the past, nmp_lookup_init_object() could both lookup all object for a
certain ifindex, and lookup all objects of a type. That fallback path
already leads to an assertion failure fora while now, so nobody should
be using this function to lookup all objects of a certain type (for
what, we have nmp_lookup_init_obj_type()).

Now, remove the fallback path, and rename the function to what it really
does.
2022-06-30 14:08:41 +02:00
Thomas Haller
902812ce49
platform: use memset() in _nmp_object_stackinit_from_class()
NMPObject is a union. It's not clear to me that C guarnatees that
designated initializers will meaningfully set all fields to zero. Use
memset() instead.
2022-06-30 14:08:40 +02:00
Beniamino Galvani
2cc02a3a1b platform: add support for {rto_min,quickack,lock-advmss} route attributes 2022-06-27 11:38:43 +02:00
Lubomir Rintel
8e6f55ce82 platform: fix build with kernels < 5.7
Fixes: 919a61bc53 ('platform/netlink: extend nl_nlmsghdr_to_str() for genl messages')

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1280
2022-06-27 09:08:00 +02:00
Thomas Haller
f8e061d7d6
platform/netlink: expose genl_ctrl_policy policy in header 2022-06-24 11:03:40 +02:00
Thomas Haller
4f405c5a07
platform/netlink: drop nl_socket_set_ext_ack() API
We just always want to set this. No need for a setter that is only
called once.
2022-06-24 11:03:39 +02:00
Thomas Haller
9cd986ba2e
platform/netlink: simplify socket flags and use boolean fields
- 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.
2022-06-24 11:03:38 +02:00
Thomas Haller
c09b37f3c7
platform/netlink: add flags argument to nl_socket_new()
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).
2022-06-24 11:03:37 +02:00
Thomas Haller
919a61bc53
platform/netlink: extend nl_nlmsghdr_to_str() for genl messages
Print more details for generic netlink messages.

Also, pass the group that we obtained via NETLINK_PKTINFO.

Also, factor out simple to-string methods.
2022-06-24 11:03:36 +02:00
Thomas Haller
51b707357d
platform/netlink: add reading NETLINK_PKTINFO in nl_recv()
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.
2022-06-24 11:03:35 +02:00
Thomas Haller
39320e26cd
platform/netlink: minor cleanup in _netlink_recv_handle()
- drop "abort_parsing" variable, it was redundant.
- rename event_valid_msg(), as this is about NETLINK_ROUTE.
- rename "err" variable to "retval".
2022-06-24 11:03:35 +02:00
Thomas Haller
88df542b6b
platform/netlink: move generic code in _netlink_recv_handle()
This also applies to genl messages. Move the code.
2022-06-24 11:03:34 +02:00
Thomas Haller
b1abd3ebdd
platform/netlink: add nl_msg_lite struct to avoid allocating netlink message
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.
2022-06-24 11:03:34 +02:00
Thomas Haller
1460adc918
platform/netlink: add const modifier for genl functions 2022-06-24 11:03:33 +02:00
Thomas Haller
59f577df56
platform/netlink: add const modifier to netlink header pointers
They are not supposed to be modified.
2022-06-23 20:36:53 +02:00
Thomas Haller
80afc691d5
platform/netlink: add "rxbuf/txbuf" arguments to nl_socket_new() 2022-06-23 20:36:52 +02:00
Thomas Haller
260d693ec4
platform/netlink: add "blocking" argument to nl_socket_new()
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.
2022-06-23 20:36:52 +02:00
Thomas Haller
2f8d8bba8f
platform: extend netlink processing of messages for different protocols
Later, the same loop should also handle genl.
2022-06-17 19:40:37 +02:00
Thomas Haller
ddbcd668ec
platform: move credential check in event_handler_recvmsgs() 2022-06-17 19:40:37 +02:00
Thomas Haller
f5d9428468
platform/netlink: add netlink_protocol argument to nl_nlmsghdr_to_str()
The meaning of the header depends on the netlink protocol. Add that parameter,
so we can also handle genl.
2022-06-17 19:40:37 +02:00
Thomas Haller
3ab66fd341
platform: move nl_recv() to separate function
Will be reused later.
2022-06-17 19:40:37 +02:00
Thomas Haller
2d211cfd5c
platform: log information about (sync) genetlink socket 2022-06-17 19:40:37 +02:00
Thomas Haller
c7fea44e47
platform/trivial: rename netlink sockets in NMLinuxPlatform
- "priv->nlh" to "priv->sk_rtnl": as we also have an genl socket,
   "nlh" is not a good name. The point is that this is rtnetlink.
   Also, "h" sounds like a handle, that is, a file descriptor.
   Make this clearer with a "sk_" prefix.

- "priv->genl" to "priv->sk_genl_sync": This socket is only used for synchronous
   operations, that is, it is passed to various independent components, that use
   it to send a request and wait for the response (while consuming all messages).
   We will have a use for a second socket, hence the "_sync" part.
   The "sk_" prefix is for consistency with "sk_rtnl".

- "priv->event_source" to "priv->rtnl_event_source". Just make it
  clearer, that this is for the rtnetlink socket. In any case,
  this field is hardly used at all, it can have a sturdy name.
2022-06-17 19:40:36 +02:00