Commit graph

33 commits

Author SHA1 Message Date
Thomas Haller
3416b00988
platform: don't put certain rtm_protocol routes in the platform cache
We need to support systems where there are hundereds of thousand routes
(e.g. BGP software).

For that, we will ignore routes that have a rtm_protocol value which was
certainly not created by NetworkManager. Before we had a BPF filer to
filter them out, but that had issues and is removed for now. Still,
don't put those routes in the platform cache and ignore them early.

Note that we still deserialize the RTM_NEWROUTE message to a NMPObject,
and don't shortcut earlier. The reason is that we should still call
delayed_action_refresh_all_in_progress() and handle the RTM_GETROUTE
response, even if the route has a different protocol. So we error out
later, shortly before putting the object in the cache. This means we
will malloc() a NMPObject and initialize it, but that is probably cheap,
compared to the first problem that the process already had to wake up
and read the netlink socket.

This restores the effective behavior of the BPF filter, albeit with a
higher overhead, as the route is rejected later. The important part for
now is that we stick to the behavior of not caching certain routes of a
certain protocol. If that can in the future be optimized (e.g. by a new
BPF filter), then we should do that. But for now that would be only a
future performance improvement, which requires new profiling first and
that has not the highest priority. Note that not caching certain routes
already should reduce the largest part of the overhead that those routes
brings. Whether this form is sufficient to reach the expected
performance goals, needs to be measured in the future.
2022-01-20 10:30:34 +01:00
Thomas Haller
c37a21ea29
Revert "platform: add bpf filter to ignore routes from routing daemons"
The socket BPF filter operates on the entire message (skb). One netlink
message (for RTM_NEWROUTE) usually contains a list of routes (struct
nlmsghdr), but the BPF filter was only looking at the first route to decide
whether to throw away the entire message. That is wrong.

This causes that we miss routes. It also means that the response to our
RTM_GETROUTE dump request could be filtered and we poll/wait (unsuccessfully)
for it:

  <trace> [1641829930.4111] platform-linux: netlink: read: wait for ACK for sequence number 26...

To get this right, the BPF filter would have to look at all routes in the
list to find out whether there are any we want to receive (and if
there are any, to pass the entire message, regardless that is might also
contain routes we want to ignore). As BPF does not support loops, that
is not trivial. Arguably, we still could do something where we look at a
bounded, unrolled number of routes, in the hope that there are not more
routes in one message that we support. The problem is that this BPF
filter is supposed to filter out massive amounts of routes, so most
messages will be filled to the brim with routes and we would have to
expect a high number of routes in the RTM_NEWROUTE that need checking.

We could still ignore routes in _new_from_nl_route(), to enter the
cache. That means, we would catch them later than with the BPF filter,
but still before a lot of the overhead of handling them. That probably
will be done next, but for now revert the commit.

This reverts commit e9ca5583e5.

https://bugzilla.redhat.com/show_bug.cgi?id=2037411
2022-01-20 10:30:30 +01:00
Thomas Haller
bcce368e55
clang-format: mark FOR_EACH_DELAYED_ACTION() as a ForEachMacro 2022-01-13 15:25:17 +01:00
Thomas Haller
56a051de56
platform: log when blocking poll() returns for reading netlink socket
Try to debug a hang in platform code, presumably during poll().
This logging seems useful for debugging this particular issue,
but it might be useful in general.
2022-01-12 13:34:44 +01:00
Thomas Haller
ba9b199cfd
platform: clamp timestamp in event_handler_read_netlink() 2022-01-12 13:34:44 +01:00
Thomas Haller
a79efac2fe
platform/trivial: rename "now_ns" to "now_nsec"
I was already doing such renaming at various places. Let's be consistent
and clear. It was (slightly) confusing was "ns" means.
2022-01-12 13:34:44 +01:00
Thomas Haller
abf39ed046
platform: log wait time in event_handler_read_netlink() 2022-01-12 13:34:43 +01:00
Thomas Haller
65cdbd355f
platform: fix type for timestamp in delayed_action_wait_for_nl_response_complete_check()
Fixes: d074ffc836 ('platform: refactor completing netlink responses in event_handler_read_netlink()')
2022-01-12 13:34:39 +01:00
Beniamino Galvani
e9ca5583e5 platform: add bpf filter to ignore routes from routing daemons
Routing daemons can add a large amount of routes to the
system. Currently NM receives netlink notifications for all those
routes and exposes them on D-Bus. With many routes, the daemon becomes
increasingly slow and uses a lot of memory.

The rtm_protocol field of the route indicates the source of the
route. From /usr/include/linux/rtnetlink.h, the allowed values are:

  #define RTPROT_UNSPEC          0
  #define RTPROT_REDIRECT        1        /* Route installed by ICMP redirects;
                                             not used by current IPv4 */
  #define RTPROT_KERNEL          2        /* Route installed by kernel */
  #define RTPROT_BOOT            3        /* Route installed during boot */
  #define RTPROT_STATIC          4        /* Route installed by administrator */

  /* Values of protocol >= RTPROT_STATIC are not interpreted by kernel;
     they are just passed from user and back as is.
     It will be used by hypothetical multiple routing daemons.
     Note that protocol values should be standardized in order to
     avoid conflicts.
   */

  #define RTPROT_GATED           8        /* Apparently, GateD */
  #define RTPROT_RA              9        /* RDISC/ND router advertisements */
  #define RTPROT_MRT            10        /* Merit MRT */
  #define RTPROT_ZEBRA          11        /* Zebra */
  #define RTPROT_BIRD           12        /* BIRD */
  #define RTPROT_DNROUTED       13        /* DECnet routing daemon */
  #define RTPROT_XORP           14        /* XORP */
  #define RTPROT_NTK            15        /* Netsukuku */
  #define RTPROT_DHCP           16        /* DHCP client */
  #define RTPROT_MROUTED        17        /* Multicast daemon */
  #define RTPROT_KEEPALIVED     18        /* Keepalived daemon */
  #define RTPROT_BABEL          42        /* Babel daemon */
  #define RTPROT_OPENR          99        /* Open Routing (Open/R) Routes */
  #define RTPROT_BGP           186        /* BGP Routes */
  #define RTPROT_ISIS          187        /* ISIS Routes */
  #define RTPROT_OSPF          188        /* OSPF Routes */
  #define RTPROT_RIP           189        /* RIP Routes */
  #define RTPROT_EIGRP         192        /* EIGRP Routes */

Since NM uses only values <= RTPROT_STATIC, plus RTPROT_RA and
RTPROT_DHCP, add a BPF filter to the netlink socket to discard
notifications for other route types.

https://bugzilla.redhat.com/show_bug.cgi?id=1861527
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1038
2021-12-09 13:19:45 +01:00
Thomas Haller
615221a99c format: reformat source tree with clang-format 13.0
We use clang-format for automatic formatting of our source files.
Since clang-format is actively maintained software, the actual
formatting depends on the used version of clang-format. That is
unfortunate and painful, but really unavoidable unless clang-format
would be strictly bug-compatible.

So the version that we must use is from the current Fedora release, which
is also tested by our gitlab-ci. Previously, we were using Fedora 34 with
clang-tools-extra-12.0.1-1.fc34.x86_64.

As Fedora 35 comes along, we need to update our formatting as Fedora 35
comes with version "13.0.0~rc1-1.fc35".
An alternative would be to freeze on version 12, but that has different
problems (like, it's cumbersome to rebuild clang 12 on Fedora 35 and it
would be cumbersome for our developers which are on Fedora 35 to use a
clang that they cannot easily install).

The (differently painful) solution is to reformat from time to time, as we
switch to a new Fedora (and thus clang) version.
Usually we would expect that such a reformatting brings minor changes.
But this time, the changes are huge. That is mentioned in the release
notes [1] as

  Makes PointerAligment: Right working with AlignConsecutiveDeclarations. (Fixes https://llvm.org/PR27353)

[1] https://releases.llvm.org/13.0.0/tools/clang/docs/ReleaseNotes.html#clang-format
2021-11-29 09:31:09 +00:00
Thomas Haller
58287cbcc0 core: rework IP configuration in NetworkManager using layer 3 configuration
Completely rework IP configuration in the daemon. Use NML3Cfg as layer 3
manager for the IP configuration of an interface. Use NML3ConfigData as
pieces of configuration that the various components collect and
configure. NMDevice is managing most of the IP configuration at a higher
level, that is, it starts DHCP and other IP methods. Rework the state
handling there.

This is a huge rework of how NetworkManager daemon handles IP
configuration. Some fallout is to be expected.

It appears the patch deletes many lines of code. That is not accurate, because
you also have to count the files `src/core/nm-l3*`, which were unused previously.

Co-authored-by: Beniamino Galvani <bgalvani@redhat.com>
2021-11-18 16:21:29 +01:00
Beniamino Galvani
864e4e6369 platform: allow disabling caching of tc objects
Introduce a construct-only property for platform objects to enable or
disable the caching of tc objects. When disabled, the netlink socket
doesn't receive netlink events for tc objects, and objects are never
added to the cache. This commit doesn't change behavior yet.
2021-09-20 13:27:16 +02:00
Beniamino Galvani
d9b2e9d7ea platform: add methods to delete tc qdiscs and tfilters
Introduce two platform methods to delete tc qdiscs and filters by
ifindex and parent.
2021-09-20 13:27:15 +02:00
Thomas Haller
4b6e119010
all: pass pointer to "struct NMUtilsIPv6IfaceId" to functions instead of struct
While NMUtilsIPv6IfaceId is only 8 bytes large, it seems unidiomatic to
pass the plain struct around.

With a "const NMUtilsIPv6IfaceId *" argument it is more clear what the
meaning of this is.

Change to use pointers.
2021-08-31 16:49:46 +02:00
Thomas Haller
bcd2c99aab
platform: require RTA_PREF support in kernel
The preference for IPv6 routes was added in kernel v4.1,
22 June 2015. It is even in latest RHEL7 kernels.

Drop trying to be compatible with such old kernels.
2021-08-31 16:41:57 +02:00
Thomas Haller
eb1c266280
platform: require extended IFA_FLAGS support in kernel
We use extended IFA_FLAGS for IFA_F_MANAGETEMPADDR (IPv6) and
IFA_F_NOPREFIXROUTE (IPv4 and IPv6).

These flags for IPv4 were added to kernel 3.14, 30 March, 2014.
The flag for IPv4 was added to kernel 4.4, 11 January 2016.
Even latest RHEL-7 kernels have backport for IFA_F_NOPREFIXROUTE
for IPv4 (rh#1221311).

Drop this. The backward compatibility code paths are likely broken
anyway, and add considerable complexity.
2021-08-31 16:41:57 +02:00
Thomas Haller
b2b50eba1b
platform: require IFLA_INET6_ADDR_GEN_MODE support in kernel
This is supported since kernel 3.17, dated 5 October, 2014. Drop the backward
compatibility for that.

It's very hard to sensibly support a mode where we set the interface up,
but prevent kernel from enabling IPv6. We would hack around that by disabling
IPv6 altogether.

But these code paths are not tested and likely make no sense. And it's hard
to implement a sensible behavior in this case anyway.
2021-08-31 16:41:57 +02:00
Thomas Haller
98ed0e9858
platform: rename "user_ipv6ll" API to "inet6_addr_gen_mode"
The term "user_ipv6ll" is confusing and not something somebody familiar
with kernel or `ip -d link` would understand.

Also, it maps a boolean to addr-gen-mode "none" or "eui64", although
there are 2 more address generation modes in kernel.

Don't abstract the underlying API, and name things as they are in
kernel.
2021-08-31 16:41:57 +02:00
Thomas Haller
98e476fe4d
platform: avoid global buffer for nm_platform_link_inet6_addrgenmode2str() 2021-08-31 16:40:29 +02:00
Wen Liang
6da4464154 platform: track kernel support for IFLA_PERM_ADDRESS
Track whether kernel supports netlink API IFLA_PERM_ADDRESS. To use the
platform cache preferably if kernel supports IFLA_PERM_ADDRESS. To fall
back to the old ethtool call directly if kernel does not support
IFLA_PERM_ADDRESS.

https://bugzilla.redhat.com/show_bug.cgi?id=1987286

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/673

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/961

Signed-off-by: Wen Liang <liangwen12year@gmail.com>
2021-08-24 16:16:27 -04:00
Wen Liang
2b70e02ef5
platform: rename nm_platform_link_get_permanent_address()
Rename `nm_platform_link_get_permanent_address()`, `link_get_permanent_address()` to
`nm_platform_link_get_permanent_address_ethtool()`, `link_get_permanent_address_ethtool()`.

Signed-off-by: Wen Liang <liangwen12year@gmail.com>
2021-08-24 21:04:21 +02:00
Wen Liang
1605fa460d
platform: update nm_platform_link_get_permanent_address() to accept NMPLinkAddress argument
Replace the arguments "buf+length" of
`nm_platform_link_get_permanent_address()` with "NMPLinkAddress *out_addr"

Signed-off-by: Wen Liang <liangwen12year@gmail.com>
2021-08-24 21:04:21 +02:00
Wen Liang
585257509f
platform: add l_perm_address in NMPlatformLink and parse it from netlink
Add `l_perm_address` in `NMPlatformLink` and add it to
`nm_platform_link_to_string`, `nm_platform_link_hash_update`,
`nm_platform_link_cmp` functions, and parse it from netlink.

Signed-off-by: Wen Liang <liangwen12year@gmail.com>
2021-08-24 21:04:20 +02:00
Thomas Haller
fa745181dc
platform/netlink: drop unused NLA_NUL_STRING type
Kernel implemente NLA_NUL_STRING type, but we don't implement
exactly the same type checks. Drop NLA_NUL_STRING and use a plain
NLA_STRING instead.
2021-08-17 13:18:07 +02:00
Thomas Haller
d0ba87a1ad
all: rename nm_utils_strbuf_*() API to nm_strbuf_*()
The "utils" part does not seem useful in the name.

Note that we also have NMStrBuf, which is named nm_str_buf_*().
There is an unfortunate similarity between the two, but it's still
distinct enough (in particular, because one takes an NMStrBuf and
the other not).
2021-08-02 09:26:42 +02:00
Thomas Haller
1f1c7b82fd
platform: mark routes in NMPlatform cache as "external" 2021-07-21 09:54:58 +02:00
Thomas Haller
4e109bacab
clang-format: use "IndentPPDirectives:None" instead of "BeforeHash"
Subjectively, I think this looks better.
2021-07-09 08:49:06 +02:00
Thomas Haller
21321ac736
clang-format: reformat code with clang 12
The format depends on the version of the tool. Now that Fedora 34 is
released, update to clang 12 (clang-tools-extra-12.0.0-0.3.rc1.fc34.x86_64).
2021-05-04 13:56:26 +02:00
Fernando Fernandez Mancera
1dfe536386 platform: introduce nm_platform_link_change_flags()
Having two functions like link_set_x() and link_set_nox() it is not a
good idea. This patch is introducing nm_platform_link_change_flags().

This allow flag modification directly, so the developer does not need to
define the virtual functions all the time everywhere.

Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
2021-04-22 18:57:30 +00:00
Thomas Haller
9eac9c846c
platform: fix using static buffer for logging in link_change_flags()
No need to make code intentionally not thread-safe.
2021-04-21 08:10:36 +02:00
Thomas Haller
3c0ae1b5da
platform: make global logging cache for NMPlatform's sysctl values thread-safe
We have a cache for sysctl values, so that we can log changes and
previous values.

When resetting the log level, we prune that cache, which is done by
_nm_logging_clear_platform_logging_cache(). That function is called
by nm_logging_setup(), which is guaranteed to only happen on the main
thread.

NMPlatform in general is not thread safe (meaning, that the same NMPlatform
instance cannot be used by multiple threads at the same time). There is however
a reasonable aim that you could use different NMPlatform instances on their
own threads.

That currently doesn't work, mainly due to nm-logging which always must
be done from the main thread -- unless we would set NM_THREAD_SAFE_ON_MAIN_THREAD
in all of NMPlatform (which would be too expensive for something we
don't actually need). That means also the sysctl getter must only be
called on the main thread an all was good already.

Still, we could have NMPlatform usable from multiple thread by setting
NM_THREAD_SAFE_ON_MAIN_THREAD. As we are almost there to have the code
thread-safe, make accessing the sysctl value cache thread-safe (even if
we currently don't actually access it from multiple thread).
2021-03-08 22:29:01 +01:00
Thomas Haller
8dbfbce9f6
platform: add NM_LINUX_PLATFORM_FROM_PRIVATE() helper function 2021-03-08 22:29:01 +01:00
Thomas Haller
604b1d0331
platform: move more platform code to src/libnm-platform/ 2021-03-05 11:27:16 +01:00
Renamed from src/core/platform/nm-linux-platform.c (Browse further)