Commit graph

247 commits

Author SHA1 Message Date
Fernando Fernandez Mancera
f900f7bc2c platform: add netlink support for bond link
sysfs is deprecated and kernel people will not add new bond options to
sysfs. Netlink is a stable API and therefore is the right method to
communicate with kernel in order to set the link options.
2022-08-04 11:18:36 +02:00
Thomas Haller
77af18c67b
platform/netlink: cleanup NLA_PUT() macro
Add parentheses around macro arguments.

Yes, it's not technically necessary when using macro arguments are
surrounded by commas. Still do it, for consistency and for not having
special exceptions to the rule.
2022-08-04 10:39:25 +02:00
Beniamino Galvani
dbf29c5450 platform: fix build with musl libc
Don't mix <net/ethernet.h> and <linux/if_ether.h>.

Fixes the following build error with musl libc:

  In file included from /usr/include/net/ethernet.h:10,
                   from ../src/libnm-platform/nm-linux-platform.c:17:
  /usr/include/netinet/if_ether.h:115:8: error: redefinition of 'struct ethhdr'
    115 | struct ethhdr {
        |        ^~~~~~
  In file included from ../src/linux-headers/ethtool.h:19,
                   from ../src/libnm-std-aux/nm-linux-compat.h:22,
                   from ../src/libnm-platform/nm-linux-platform.c:10:
  /usr/include/linux/if_ether.h:169:8: note: originally defined here
    169 | struct ethhdr {
        |        ^~~~~~

Fixes: dc98ab807c ('platform: include "linux-headers" via "libnm-std-aux/nm-linux-compat.h"')
2022-07-27 18:46:01 +02:00
Thomas Haller
0b9384187b
platform: fix identity for MPTCP NMPObject to honor port 2022-07-26 13:09:20 +02:00
Thomas Haller
766349879e
platform/trivial: add code comments for NMPGlobalTracker 2022-07-26 13:09:19 +02:00
Thomas Haller
d3c9bb4666
platform: rename file "nmp-route-manager.[hc]" to "nmp-global-tracker.[hc]" 2022-07-26 12:45:55 +02:00
Thomas Haller
bf248e0400
platform: rename NMPRouteManager to NMPGlobalTracker
NetworkManager primarily manages interfaces in an independent fashion.
That means, whenever possible, we want to have a interface specific
view. In many cases, the underlying kernel API also supports that view.
For example, when configuring IP addresses or unicast routes, we do so
per interfaces and don't need a holistic view.

However, that is not always sufficient. For routing rules and certain
route types (blackhole, unreachable, etc), we need a system wide view
of all the objects in the network namespace.

Originally, NMPRulesManager was added to track routing rules. Then, it
was extended to also track certain route types, and the API was renamed to
NMPRouteManager.

This will also be used to track MPTCP addresses.

So rename again, to give it a general name that is suitable for what it
does. Still, the name is not great (suggestion welcome), but it should
cover the purpose of the API well enough. And it's the best I came
up with.

Rename.
2022-07-26 12:43:44 +02:00
Thomas Haller
e466ad62e5
platform: set the scope for IPv4 loopback address to "host"
For IPv6, kernel does not accept the ifa_scope parameter and always
determines the scope based on the address itself.

For IPv4, it honors whatever scope the user sets via netlink.
NetworkManager does not allow to directly configure the address
scope, but autodetects it.

Use nm_platform_ip4_address_get_scope() for detecting the scopt.

This also fixes the issue that to detect loopback addresses 127.0.0.0/8
and use scope "host".

Try:

  $ nmcli device modify "$IFACE" +ipv4.addresses 127.0.0.5/8
2022-07-26 12:28:05 +02:00
Thomas Haller
e25b7a579e
platform: add nm_platform_ip{4,6,}_address_get_scope() helper 2022-07-26 12:28:05 +02:00
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