Commit graph

102 commits

Author SHA1 Message Date
Thomas Haller
2c8dcbeaf9
all: use nm_g_array_append_new() at various places 2022-09-15 12:39:06 +02:00
Thomas Haller
c28dd78c05 platform: use signed int for NMPlatformLnkBond.primary
On netlink API, the attribute is indeed u32. However, this is an ifindex
which in most other kernel APIs and in NetworkManager code is a signed
integer. Note that of course kernel would only ever assign numbers that
are valid ifindexes, thus in the suitable range.
2022-09-13 10:31:05 +02:00
Thomas Haller
6d95c406db platform: don't fallback to IFLA_BOND_ACTIVE_SLAVE for the primary
The IFLA_BOND_ACTIVE_SLAVE and IFLA_BOND_PRIMARY are not the same.
If the primary is not set, then that's it. Don't fallback.

Only NetworkManager API deprecated "active-slave" and uses it as
alias for "primary". That does not mean, kernel/netlink does that.
2022-09-13 10:30:58 +02:00
Thomas Haller
08eff4c46e
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
  `nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.

- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
  of our wrapper is chosen to be familiar with the libc underlying
  function. With this, also name functions that are about string
  representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
  `nm_inet6_*()`. For example, `nm_inet_parse_str()`,
  `nm_inet_is_normalized()`.

<<<<

  R() {
     git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
  }

  R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX          NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
  R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX          NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
  R NM_UTILS_INET_ADDRSTRLEN                   NM_INET_ADDRSTRLEN
  R _nm_utils_inet4_ntop                       nm_inet4_ntop
  R _nm_utils_inet6_ntop                       nm_inet6_ntop
  R _nm_utils_ip4_get_default_prefix           nm_ip4_addr_get_default_prefix
  R _nm_utils_ip4_get_default_prefix0          nm_ip4_addr_get_default_prefix0
  R _nm_utils_ip4_netmask_to_prefix            nm_ip4_addr_netmask_to_prefix
  R _nm_utils_ip4_prefix_to_netmask            nm_ip4_addr_netmask_from_prefix
  R nm_utils_inet4_ntop_dup                    nm_inet4_ntop_dup
  R nm_utils_inet6_ntop_dup                    nm_inet6_ntop_dup
  R nm_utils_inet_ntop                         nm_inet_ntop
  R nm_utils_inet_ntop_dup                     nm_inet_ntop_dup
  R nm_utils_ip4_address_clear_host_address    nm_ip4_addr_clear_host_address
  R nm_utils_ip4_address_is_link_local         nm_ip4_addr_is_link_local
  R nm_utils_ip4_address_is_loopback           nm_ip4_addr_is_loopback
  R nm_utils_ip4_address_is_zeronet            nm_ip4_addr_is_zeronet
  R nm_utils_ip4_address_same_prefix           nm_ip4_addr_same_prefix
  R nm_utils_ip4_address_same_prefix_cmp       nm_ip4_addr_same_prefix_cmp
  R nm_utils_ip6_address_clear_host_address    nm_ip6_addr_clear_host_address
  R nm_utils_ip6_address_same_prefix           nm_ip6_addr_same_prefix
  R nm_utils_ip6_address_same_prefix_cmp       nm_ip6_addr_same_prefix_cmp
  R nm_utils_ip6_is_ula                        nm_ip6_addr_is_ula
  R nm_utils_ip_address_same_prefix            nm_ip_addr_same_prefix
  R nm_utils_ip_address_same_prefix_cmp        nm_ip_addr_same_prefix_cmp
  R nm_utils_ip_is_site_local                  nm_ip_addr_is_site_local
  R nm_utils_ipaddr_is_normalized              nm_inet_is_normalized
  R nm_utils_ipaddr_is_valid                   nm_inet_is_valid
  R nm_utils_ipx_address_clear_host_address    nm_ip_addr_clear_host_address
  R nm_utils_parse_inaddr                      nm_inet_parse_str
  R nm_utils_parse_inaddr_bin                  nm_inet_parse_bin
  R nm_utils_parse_inaddr_bin_full             nm_inet_parse_bin_full
  R nm_utils_parse_inaddr_prefix               nm_inet_parse_with_prefix_str
  R nm_utils_parse_inaddr_prefix_bin           nm_inet_parse_with_prefix_bin
  R test_nm_utils_ip6_address_same_prefix      test_nm_ip_addr_same_prefix

  ./contrib/scripts/nm-code-format.sh -F
2022-08-25 19:05:51 +02:00
Thomas Haller
ce635c4339
platform: add dump/update function for MPTCP addresses
Since the generic netlink API does (currently) not support notifications
about changes of the MPTCP addresses, we won't get notifications when
they change, and it seems wrong to put such things in the NMPlatform
cache.

We can just get the list of endpoints by polling, so add a function
nm_platform_mptcp_addrs_dump() for that.

Also, add nm_platform_mptcp_addr_update() which can add/remove/update
MPTCP addresses.
2022-08-09 08:02:50 +02:00
Thomas Haller
8bdd416972
platform: use nlmsg_parse_error() in _netlink_recv_handle() 2022-08-09 08:02:42 +02:00
Thomas Haller
92fe4c383e
platform: use NLA_NEST_END() macro in _wireguard_create_change_nlmsgs() 2022-08-09 08:02:42 +02:00
Thomas Haller
c74c783c28
platform/netlink: make callback parameters to nl_recvmsg() const 2022-08-09 08:02:38 +02:00
Thomas Haller
338672394f
platform: fix compilation for new bond options
CentOS 7's headers don't yet contains IFLA_BOND_PEER_NOTIF_DELAY.
Define it ourselves.

Fixes: f900f7bc2c ('platform: add netlink support for bond link')
2022-08-08 14:27:21 +02:00
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
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
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
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
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
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
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
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
Beniamino Galvani
2cc02a3a1b platform: add support for {rto_min,quickack,lock-advmss} route attributes 2022-06-27 11:38:43 +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
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
Thomas Haller
aa2fd36db4
platform: require generic netlink socket
Sockets are really a fundamental thing we require to operate.
We cannot meaningfully operate, if we fail to create them.
That is also why a too low file descriptor limit is fatal
and unsupported. This is similar with out of memory situations.

Just require that we always are able to create the generic
netlink socket.
2022-06-17 19:40:36 +02:00
Thomas Haller
9c8b957704
platform: drop _genl_sock() function and directly access data 2022-06-17 19:40:36 +02:00
Thomas Haller
67d64fd4e5
platform/netlink: also set NETLINK_EXT_ACK for genl socket
There are only two callers of nl_socket_new(). One for NETLINK_GENERIC
and one for NETLINK_ROUTE.

We already were enabling ext-ack for the rtnetlink socket. Also enable
it for the genl socket.

Do that, but just moving this inside nl_socket_new(). I cannot imagine a
case where we don't want this.
2022-06-17 19:40:36 +02:00