Commit graph

551 commits

Author SHA1 Message Date
Thomas Haller
f9fe215599 platform: compare routing rules according to kernel support for FRA_PROTOCOL
For routes and routing rules, kernel uses a certain (not stictly defined) set
of attributes to decide whether to routes/rules are identical.

That is a problem, as different kernel versions disagree on whether
two routes/rules are the same (EEXIST) or not.

Note that when NetworkManager tries to add a rule with protocol set to
anything but RTPROT_UNSPEC, then kernel will ignore the attribute if it
doesn't have support for it. Meaning: the added rule will have a
different protocol setting then intended.

Note that NMPRulesManager will add a rule if it doesn't find it in the
platform cache so far. That means, when looking into the platform cache
we must ignore or honor the protocol like kernel does.

This does not only affect FRA_PROTOCOL, but all attributes where kernel
and NetworkManager disagrees. But the protocol is the most prominent
one, because the rules tracked by nmp_rules_manager_track_default()
specify the protocol.

(cherry picked from commit ef4f8ccf6d)
2019-04-18 11:19:26 +02:00
Thomas Haller
a9cf54c4ce platform: detect kernel support for FRA_L3MDEV
(cherry picked from commit eba4fd56f5)
2019-04-18 11:19:26 +02:00
Thomas Haller
ff686dd6c1 platform: detect kernel support for FRA_UID_RANGE
(cherry picked from commit 1dd1dcb81e)
2019-04-18 11:19:26 +02:00
Thomas Haller
4127583189 platform: detect kernel support for FRA_IP_PROTO, FRA_SPORT_RANGE, FRA_DPORT_RANGE
(cherry picked from commit 91252bb2fb)
2019-04-18 11:19:26 +02:00
Thomas Haller
6bfce3587e platform: detect kernel support for FRA_PROTOCOL
(cherry picked from commit cd62d43963)
2019-04-18 11:19:26 +02:00
Thomas Haller
bf36fa11d2 platform: refactor detecting kernel features
Next we will need to detect more kernel features. First refactor the
handling of these to require less code changes and be more efficient.
A plain nm_platform_kernel_support_get() only reqiures to access an
array in the common case.

The other important change is that the function no longer requires a
NMPlatform instance. This allows us to check kernel support from
anywhere. The only thing is that we require kernel support to be
initialized before calling this function. That means, an NMPlatform
instance must have detected support before.

(cherry picked from commit ee269b318e)
2019-04-18 11:19:26 +02:00
Beniamino Galvani
da204257b1 all: support bridge vlan ranges
In some cases it is convenient to specify ranges of bridge vlans, as
already supported by iproute2 and natively by kernel. With this commit
it becomes possible to add a range in this way:

 nmcli connection modify eth0-slave +bridge-port.vlans "100-200 untagged"

vlan ranges can't be PVIDs because only one PVID vlan can exist.

https://bugzilla.redhat.com/show_bug.cgi?id=1652910
(cherry picked from commit 7093515777)
2019-04-18 09:53:18 +02:00
Thomas Haller
dc64745dd8 platform: set errno to ENOENT for nm_platform_sysctl_get() 2019-04-04 15:35:13 +02:00
Beniamino Galvani
fafde171ea platform: add support for bridge vlans 2019-03-26 17:19:39 +01:00
Thomas Haller
b8398b9e79 platform: add NMPRulesManager for syncing routing rules
Routing rules are unlike addresses or routes not tied to an interface.
NetworkManager thinks in terms of connection profiles. That works well
for addresses and routes, as one profile configures addresses and routes
for one device. For example, when activating a profile on a device, the
configuration does not interfere with the addresses/routes of other
devices. That is not the case for routing rules, which are global, netns-wide
entities.

When one connection profile specifies rules, then this per-device configuration
must be merged with the global configuration. And when a device disconnects later,
the rules must be removed.

Add a new NMPRulesManager API to track/untrack routing rules. Devices can
register/add there the routing rules they require. And the sync method will
apply the configuration. This is be implemented on top of NMPlatform's
caching API.
2019-03-13 09:47:37 +01:00
Thomas Haller
9992ac1cf8 platform: add routing-rule add/delete netlink functions 2019-03-13 09:03:59 +01:00
Thomas Haller
9934a6a0e3 platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.

Rules are special in two ways:

- they don't have an ifindex. That makes them different from all other
  currently existing NMPlatform* types, which have an "ifindex" field and
  "implement" NMPlatformObjWithIfindex.

- they have an address family, but contrary to addresses and routes, there
  is only one NMPlatformRoutingRule object to handle both address
  families.

Both of these points require some special considerations.

Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.

Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-03-13 09:03:59 +01:00
Thomas Haller
7c5ad2d910 platform: drop unused nm_platform_refresh_all()
The function is unused. It would require redesign to work with
future changes, and since it's unused, just drop it.

The long reasoning is:

    Currently, a refresh-all is tied to an NMPObjectType. However, with
    NMPObjectRoutingRule (for policy-routing-rules) that will no longer
    be the case.

    That is because NMPObjectRoutingRule will be one object type for
    AF_INET and AF_INET6. Contrary to IPv4 addresses and routes, where
    there are two sets of NMPObject types.

    The reason is, that it's preferable to treat IPv4 and IPv6 objects
    similarly, that is: as the same type with an address family property.

    That also follows netlink, which uses RTM_GET* messages for both
    address families, and the address family is expressed inside the
    message.

    But then an API like nm_platform_refresh_all() makes little sense,
    it would require at least an addr_family argument. But since the
    API is unused, just drop it.
2019-03-13 09:03:59 +01:00
Thomas Haller
ac4a1deba0 platform: add NMPlatformObjWithIfindex helper structure for handling NMPObject types
Until now, all implemented NMPObject types have an ifindex field (from
links, addresses, routes, qdisc to tfilter).

The NMPObject structure contains a union of all available types, that
makes it easier to down-case from an NMPObject pointer to the actual
content.

The "object" field of NMPObject of type NMPlatformObject is the lowest
common denominator.

We will add NMPlatformRoutingRules (for policy routing rules). That type
won't have an ifindex field.

Hence, drop the "ifindex" field from NMPlatformObject type. But also add
a new type NMPlatformObjWithIfindex, that can represent all types that
have an ifindex.
2019-03-13 09:03:59 +01:00
Thomas Haller
7259195a91 platform: unify IPv4 and IPv6 variables for NMPlatformVTableRoute 2019-03-13 09:03:59 +01:00
Thomas Haller
7451a6a649 core: use nm_utils_memeqzero_secret() for printing WireGuard key 2019-03-07 17:54:25 +01:00
Marco Trevisan (Treviño)
73005fcf5b nm: Fix syntax on introspection annotations
Various annotations were added using multiple colons, while only one has
to be added or g-ir-introspect will consider them part of the description

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/94
2019-03-07 10:04:41 +01:00
Thomas Haller
a3d4dea61f platform: print persistent-keepalive setting of WireGuard peers 2019-02-14 08:00:29 +01:00
Thomas Haller
153b41fa97 platform: add peer_flags argument to nm_platform_link_wireguard_change() 2019-02-14 08:00:29 +01:00
Thomas Haller
1e1b03c089 platform: add flags for setting individual WireGuard options of link 2019-02-14 08:00:29 +01:00
Thomas Haller
2ed01e2e34 platform: add change-flags argument to platform's link_wireguard_change()
We will need more flags.

WireGuard internal tools solve this by embedding the change flags inside
the structure that corresponds to NMPlatformLnkWireGuard. We don't do
that, NMPlatformLnkWireGuard is only for containing the information about
the link.
2019-02-14 08:00:29 +01:00
Thomas Haller
737ab51472 all: include "nm-utils/nm-errno.h" via "nm-default.h" 2019-02-12 08:50:28 +01:00
Thomas Haller
a3370af3a8 all: drop unnecessary includes of <errno.h> and <string.h>
"nm-macros-interal.h" already includes <errno.h> and <string.h>.
No need to include it everywhere else too.
2019-02-12 08:50:28 +01:00
Thomas Haller
6f8c7b580d platform: add @replace_peers argument to nm_platform_link_wireguard_change()
The caller may not wish to replace existing peers, but only update/add
the peers explicitly passed to nm_platform_link_wireguard_change().

I think that is in particular interesting, because for the most part
NetworkManager will configure the same set of peers over and over again
(whenever we resolve the DNS name of an IP endpoint of the WireGuard
peer).

At that point, it seems disruptive to drop all peers and re-add them
again. Setting @replace_peers to %FALSE allows to only update/add.
2019-01-22 16:30:23 +01:00
Thomas Haller
78ce4307c0 platform: add and use nm_sock_addr_union_to_string()
We still don't use getnameinfo(). This is used for logging,
where we want to see a string representation that is as close
as possible to the actual bytes (to spot differences). It should
not be obfuscated by a libc function out of our control.

Also fix the notation for the IPv6 scope ID to use the common '%'
character.
2019-01-22 16:30:23 +01:00
Thomas Haller
3263cab596 all: add static assertion for maximumg alloca() allocated buffer
Add a compile time check that the buffer that we allocate on the stack
is reasonably small.
2019-01-15 09:52:01 +01:00
Thomas Haller
a5c894c35f platform: create wireguard netdev interface
The netlink code for WG_CMD_SET_DEVICE is strongly inspired by
WireGuard ([1]) and systemd ([2]).

Currently, nm_platform_link_wireguard_change() always aims to reset
all peers and allowed-ips settings. I think that should be improved
in the future, to support only partial updates.

[1] https://git.zx2c4.com/WireGuard/tree/contrib/examples/embeddable-wg-library/wireguard.c?id=5e99a6d43fe2351adf36c786f5ea2086a8fe7ab8#n1073
[2] 04ca4d191b/src/network/netdev/wireguard.c (L48)
2019-01-09 16:46:41 +01:00
Thomas Haller
0713a6996c platform: track wireguard endpoint as sockaddr struct
We need to track the IPv6 endpoint as struct sockaddr_in6, so that
we have access to the scope-id.
2019-01-09 16:46:41 +01:00
Thomas Haller
fce3243f12 shared/trivial: rename nm_utils_mem_all_zero() to nm_utils_memeqzero()
in systemd/systemd, systemd/casync, and rustyrussel/ccan (github) this
function is called "memeqzero()". Rename, to use a more popular name.
2019-01-09 16:46:41 +01:00
Thomas Haller
2ddfa5b265 platform: fix nm_platform_wireguard_peer_to_string()
Fixes: 62d14e1884
2018-12-30 15:17:11 +01:00
Thomas Haller
691e5d5cc9 platform: return platform-error from link-add function
We need more information what failed. Don't only return success/failure,
but an error number.

Note that we still don't actually return an error number. Only
the link_add() function is changed to return an nm-error integer.
2018-12-27 21:33:59 +01:00
Thomas Haller
d18f40320d platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.

This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.

The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-27 21:33:59 +01:00
Thomas Haller
a51c09dc12 all: don't use static buffer for nm_utils_inet*_ntop()
While nm_utils_inet*_ntop() accepts a %NULL buffer to fallback
to a static buffer, don't do that.

I find the possibility of using a static buffer here error prone
and something that should be avoided. There is of course the downside,
that in some cases it requires an additional line of code to allocate
the buffer on the stack as auto-variable.
2018-12-19 09:23:08 +01:00
Thomas Haller
91b5babff2 core/trivial: rename nm_platform_sysctl_set_ip6_hop_limit_safe()
Now that we have other helper function on platfrom for setting
IP configuration sysctls, rename the function to set the hop-limit
to match the pattern.
2018-12-19 09:05:12 +01:00
Thomas Haller
7fa398d596 platform: add nm_platform_sysctl_ip_conf_*() wrappers 2018-12-19 09:05:12 +01:00
Beniamino Galvani
e01a7c1154 core: use NMTernary for SR-IOV autoprobe-drivers 2018-12-12 14:38:18 +01:00
Thomas Haller
f94142284d platform: don't consult cache before invoking netlink operation
Checking whether the link exists in the cache, before talking to kernel
serves no purpose.

- in all cases, the caller already has a good indication that the link
  in fact exists. That is, because the caller makes decisions on what to
  do, based on what platform told it earlier. Thus, the check usually succeeds
  anyway.

- in the unexpected case it doesn't succeed, we

  - should not silently return without logging at least a message

  - we possibly still want to send the netlink message to kernel,
    just to have it fail. Note that the ifindex is indeed the identifier
    for the link, so there is no danger of accidentally killing the
    wrong link.
    Well, theoretically there is, because the kernel's ifindex counter can
    wrap or get reused when moving links between namespaces. But checking
    the cache would not protect against that anyway! Worst case, the cache
    would already have the impostor link and would not prevent from doing
    the wrong thing. After all, they do have the same identifier, so how
    would we know that this is in fact a different link?
2018-12-03 12:26:16 +01:00
Thomas Haller
945c904f95 platform: assert against valid ifindex and remove duplicate assertions
We want that all code paths assert strictly and gracefully.

That means, if we have function nm_platform_link_get() which calls
nm_platform_link_get_obj(), then we don't need to assert the same things
twice. Don't have the calling function assert itself, if it is obvious
that the first thing that it does, is calling a function that itself
asserts the same conditions.

On the other hand, it simply indicates a bug passing a non-positive
ifindex to any of these platform functions. No longer let
nm_platform_link_get_obj() handle negative ifindex gracefully. Instead,
let it directly pass it to nmp_cache_lookup_link(), which eventually
does a g_return_val_if_fail() check. This quite possible enables
assertions on a lot of code paths. But note that g_return_val_if_fail()
is graceful and does not lead to a crash (unless G_DEBUG=fatal-criticals
is set for debugging).
2018-12-03 12:26:16 +01:00
Thomas Haller
1c7b747f8c platform: move assertion from nm_platform_link_get() to nm_platform_link_get_obj()
We want to assert for valid input arguments, but we don't want
multiple assertions for the same.

Move the assertion from nm_platform_link_get() to
nm_platform_link_get_obj().

That way, nm_platform_link_get_obj() also checks the input arguments.
At the same time, nm_platform_link_get() gets simpler and still does
the same amount of assertions.
2018-12-03 12:26:16 +01:00
Thomas Haller
b445b1f8fe platform: add nm_platform_link_get_ifi_flags() helper
Add helper nm_platform_link_get_ifi_flags() to access the
ifi-flags.

This replaces the internal API _link_get_flags() and makes it public.
However, the return value also allows to distinguish between errors
and valid flags.

Also, consider non-visible links. These are links that are in netlink,
but not visible in udev. The ifi-flags are inherrently netlink specific,
so it seems wrong to pretend that the link doesn't exist.
2018-11-29 13:50:10 +01:00
Thomas Haller
37e47fbdab build: avoid header conflict for <linux/if.h> and <net/if.h> with "nm-platform.h"
In the past, the headers "linux/if.h" and "net/if.h" were incompatible.
That means, we can either include one or the other, but not both.
This is fixed in the meantime, however the issue still exists when
building against older kernel/glibc.

That means, including one of these headers from a header file
is problematic. In particular if it's a header like "nm-platform.h",
which itself is dragged in by many other headers.

Avoid that by not including these headers from "platform.h", but instead
from the source files where needed (or possibly from less popular header
files).

Currently there is no problem. However, this allows an unknowing user to
include <net/if.h> at the same time with "nm-platform.h", which is easy
to get wrong.
2018-11-12 16:02:35 +01:00
Lubomir Rintel
0573656eeb platform/wpan: allow setting channel 2018-10-07 15:46:02 +02:00
Lubomir Rintel
8f107f5c00 platform: bring back the interface name to log messages
Fixes: ecf607cce6
2018-10-01 11:45:57 +02:00
Lubomir Rintel
ecf607cce6 platform: log the interface names 2018-10-01 10:26:05 +02:00
Rafael Fontenelle
34fd628990 Fix typos
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/21

[thaller@redhat.com: fix generated clients/common/settings-docs.h.in file
   and fix wrong change in src/systemd/src/libsystemd/sd-event/sd-event.c]
2018-09-30 21:14:55 +02:00
luz.paz
f985b6944a docs: misc. typos
Found via `codespell -q 3 --skip="*.po"`

https://github.com/NetworkManager/NetworkManager/pull/203
2018-09-15 09:08:03 +02:00
Thomas Haller
62d14e1884 platform/wireguard: rework parsing wireguard links in platform
- previously, parsing wireguard genl data resulted in memory corruption:

  - _wireguard_update_from_allowedips_nla() takes pointers to

      allowedip = &g_array_index (buf->allowedips, NMWireGuardAllowedIP, buf->allowedips->len - 1);

    but resizing the GArray will invalidate this pointer. This happens
    when there are multiple allowed-ips to parse.

  - there was some confusion who owned the allowedips pointers.
    _wireguard_peers_cpy() and _vt_cmd_obj_dispose_lnk_wireguard()
    assumed each peer owned their own chunk, but _wireguard_get_link_properties()
    would not duplicate the memory properly.

- rework memory handling for allowed_ips. Now, the NMPObjectLnkWireGuard
  keeps a pointer _allowed_ips_buf. This buffer contains the instances for
  all peers.
  The parsing of the netlink message is the complicated part, because
  we don't know upfront how many peers/allowed-ips we receive. During
  construction, the tracking of peers/allowed-ips is complicated,
  via a CList/GArray. At the end of that, we prettify the data
  representation and put everything into two buffers. That is more
  efficient and simpler for user afterwards. This moves complexity
  to the way how the object is created, vs. how it is used later.

- ensure that we nm_explicit_bzero() private-key and preshared-key. However,
  that only works to a certain point, because our netlink library does not
  ensure that no data is leaked.

- don't use a "struct sockaddr" union for the peer's endpoint. Instead,
  use a combintation of endpoint_family, endpoint_port, and
  endpoint_addr.

- a lot of refactoring.
2018-09-07 11:24:17 +02:00
Thomas Haller
c085b6e3a7 platform/ethtool: add code to get/set offload features via ethtool
Also, add two more features "tx-tcp-segmentation" and
"tx-tcp6-segmentation". There are two reasons for that:

 - systemd-networkd supports setting these two features,
   so lets support them too (apparently they are important
   enough for networkd).

 - these two features are already implicitly covered by "tso".
   Like for the "ethtool" program, "tso" is an alias for several
   actual features. By adding two features that are already
   also covered by an alias (which sets multiple kernel names
   at once), we showcase how aliases for the same feature can
   coexist. In particular, note how setting
   "tso on tx-tcp6-segmentation off" will behave as one would
   expect: all 4 tso features covered by the alias are enabled,
   except that particular one.
2018-08-10 10:38:19 +02:00
Javier Arteaga
edd5cf1a3c platform: rename instances of Wireguard to WireGuard
Respect WireGuard canonical capitalization on identifiers.
As per discussion on:
https://github.com/NetworkManager/NetworkManager/pull/162
2018-08-06 08:34:27 +02:00
Beniamino Galvani
8720dd3df1 platform: add support for changing VF attributes 2018-07-11 16:16:22 +02:00