Commit Graph

62 Commits

Author SHA1 Message Date
Thomas Haller
e9c76f375b platform: avoid valgrind warning about uninitialised memory in _ioctl_call()
==6207== Syscall param ioctl(SIOCETHTOOL) points to uninitialised byte(s)
==6207==    at 0x514603B: ioctl (syscall-template.S:78)
==6207==    by 0x19FC2F: _ioctl_call (nm-platform-utils.c:183)
==6207==    by 0x1A026B: _ethtool_call_handle (nm-platform-utils.c:319)
==6207==    by 0x1A031F: ethtool_get_stringset (nm-platform-utils.c:378)
==6207==    by 0x1A03BC: ethtool_get_stringset_index (nm-platform-utils.c:414)
==6207==    by 0x1A181E: nmp_utils_ethtool_supports_vlans (nm-platform-utils.c:912)
==6207==    by 0x1756D7: link_supports_vlans (nm-linux-platform.c:6508)
==6207==    by 0x1A81D8: nm_platform_link_supports_vlans (nm-platform.c:1536)
==6207==    by 0x14B96B: test_internal (test-link.c:602)
==6207==    by 0x4F5C18D: test_case_run (gtestutils.c:2597)
==6207==    by 0x4F5C18D: g_test_run_suite_internal (gtestutils.c:2685)
==6207==    by 0x4F5BF33: g_test_run_suite_internal (gtestutils.c:2697)
==6207==    by 0x4F5C679: g_test_run_suite (gtestutils.c:2772)
==6207==    by 0x4F5C694: g_test_run (gtestutils.c:2007)
==6207==    by 0x166B4D: main (test-common.c:2092)
==6207==  Address 0x1ffeffeecf is on thread 1's stack
==6207==  in frame #1, created by _ioctl_call (nm-platform-utils.c:110)
==6207==

"ifname" is the stack-allocated array "known_ifnames" of suitable
IFNAMSIZ bytes. But it may not be fully initialized, so using memcpy()
to copy the string leads to unintialized warning.

We really should only copy the valid bytes, either with strcpy() or our
nm_utils_ifname_cpy() wrapper.

Fixes: 856322562e ('platform/ethtool,mii: retry ioctl when interface name was renamed for ehttool/mii')
2019-05-16 10:17:04 +02:00
Thomas Haller
065d891402 platform: use memset() to initialize ifr struct in _ioctl_call()
"struct ifreq" contains a union field, and initalizing the struct is not
guaranteed to fill all bytes with zero (it only sets the first union
member to zero).

Since we later return the entire struct, ensure that it's initialized to
all zero by using memset().
2019-05-16 08:51:56 +02:00
Thomas Haller
856322562e platform/ethtool,mii: retry ioctl when interface name was renamed for ehttool/mii
ethtool/mii API is based on the ifname. As an interface can be renamed,
this API is inherently racy. We would prefer to use the ifindex instead.
The ifindex of a device cannot change (altough it can repeat, which opens a
different race *sigh*).

Anyway, we were already trying to minimize the race be resolving the
name from ifindex immediately before the call to ethtool/mii.

Do better than that. Now resolve the name before and after the call. If
the name changed in the meantime, we have an indication that a race
might have happend (but we cannot be sure).

Note that this can not catch every possible kind of rename race. If you are very
unlucky a swapping of names cannot be detected.

For getters this is relatively straight forward. Just retry when we
have an indication to fall victim to a race (up to a few times). Yes, we
still cannot be 100% sure, but this should be very reliable in practice.

For setters (that modify the device) we also retry. We do so under the
assumption that setting the same options multiple times has no bad effect.
Note that for setters the race of swapping interface names is particularly
bad. If we hit a very unlucky race condition, we might set the setting on
the wrong interface and there is nothing we can do about it. The retry only
ensures that eventually we will set it on the right interface.

Note that this involves one more if_indextoname() call for each operation (in
the common case when there is no renaming race). In cases where we make
multiple ioctl calls, we cache and reuse the information though. So, for such
calls the overhead is even smaller.
2019-05-07 09:41:19 +02:00
Thomas Haller
284ac92eee shared: build helper "libnm-libnm-core-{intern|aux}.la" library for libnm-core
"libnm-core" implements common functionality for "NetworkManager" and
"libnm".

Note that clients like "nmcli" cannot access the internal API provided
by "libnm-core". So, if nmcli wants to do something that is also done by
"libnm-core", , "libnm", or "NetworkManager", the code would have to be
duplicated.

Instead, such code can be in "libnm-libnm-core-{intern|aux}.la".
Note that:

  0) "libnm-libnm-core-intern.la" is used by libnm-core itsself.
     On the other hand, "libnm-libnm-core-aux.la" is not used by
     libnm-core, but provides utilities on top of it.

  1) they both extend "libnm-core" with utlities that are not public
     API of libnm itself. Maybe part of the code should one day become
     public API of libnm. On the other hand, this is code for which
     we may not want to commit to a stable interface or which we
     don't want to provide as part of the API.

  2) "libnm-libnm-core-intern.la" is statically linked by "libnm-core"
     and thus directly available to "libnm" and "NetworkManager".
     On the other hand, "libnm-libnm-core-aux.la" may be used by "libnm"
     and "NetworkManager".
     Both libraries may be statically linked by libnm clients (like
     nmcli).

  3) it must only use glib, libnm-glib-aux.la, and the public API
     of libnm-core.
     This is important: it must not use "libnm-core/nm-core-internal.h"
     nor "libnm-core/nm-utils-private.h" so the static library is usable
     by nmcli which couldn't access these.

Note that "shared/nm-meta-setting.c" is an entirely different case,
because it behaves differently depending on whether linking against
"libnm-core" or the client programs. As such, this file must be compiled
twice.

(cherry picked from commit af07ed01c0)
2019-04-18 20:07:44 +02:00
Thomas Haller
9beed4f661 all: replace strerror() calls with nm_strerror_native() 2019-02-12 08:50:28 +01:00
Thomas Haller
a4fb6ddfca all: replace g_strerror() calls with nm_strerror_native() 2019-02-12 08:50:28 +01:00
Thomas Haller
4d9918aac2 all: assert that native errno numbers are positive
Use the NM_ERRNO_NATIVE() macro that asserts that these errno numbers are
indeed positive. Using the macro also serves as a documentation of what
the meaning of these numbers is.

That is often not obvious, whether we have an nm_errno(), an nm_errno_native()
(from <errno.h>), or another error number (e.g. WaitForNlResponseResult). This
situation already improved by merging netlink error codes (nle),
NMPlatformError enum and <errno.h> as nm_errno(). But we still must
always be careful about not to mix error codes from different
domains or transform them appropriately (like nm_errno_from_native()).
2019-02-12 08:50:28 +01:00
Thomas Haller
047998f80a all: cache errno in local variable before using it 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
d25ed0820c all: don't use "static inline" in source files
For static functions inside a module, the compiler determines on its own
whether to inline the function.

Also, "inline" was used at some places that don't immediatly look like
candidates for inlining. It was most likely a copy&paste error.
2019-02-06 09:31:00 +01:00
Thomas Haller
9096b5572d platform: use nm_steal_fd() in nmp_utils_sysctl_open_netdir() 2018-12-27 21:33:59 +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
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
f3f5d5c900 platform/trivial: add FIXME comment to use new ethtool API to set link settings 2018-09-06 10:30:51 +02:00
Thomas Haller
da109a291c all/ethtool: add support for all currently supported kernel features
As of upstream kernel v4.18-rc8.

Note that we name the features like they are called in ethtool's
ioctl API ETH_SS_FEATURES.

Except, for features like "tx-gro", which ethtool utility aliases
as "gro". So, for those features where ethtool has a built-in,
alternative name, we prefer the alias.

And again, note that a few aliases of ethtool utility ("sg", "tso", "tx")
actually affect more than one underlying kernel feature.

Note that 3 kernel features which are announced via ETH_SS_FEATURES are
explicitly exluded because kernel marks them as "never_changed":

    #define NETIF_F_NEVER_CHANGE (NETIF_F_VLAN_CHALLENGED | \
                                  NETIF_F_LLTX | NETIF_F_NETNS_LOCAL)
2018-08-10 10:38:19 +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
Thomas Haller
14f963cde3 platform/mii: use SocketHandle also for nmp_utils_mii_supports_carrier_detect()
There is little difference in practice because there is only one caller.
Still re-use the SocketHandle also for mii. If only, to make it clear
that SocketHandle is not only suitable for ethtool, but also mii.
2018-08-10 10:38:19 +02:00
Thomas Haller
bdd9f7482c platform/ethtool: add SocketHandle to reuse socket for ethtool requests
Previously, each call to ethtool_get() would resolve the ifindex and
create a new socket for the ethtool request.

This is partly done, because ethtool only supports making requests by
name. Since interfaces can be renamed, this is inherrently racy. So,
we want to fetch the latest name shortly before making the request.

Some functions like nmp_utils_ethtool_supports_vlans() require multiple
ioctls. And next, we will introduce more ethtool functions, that make an
even larger number of individual requests.

Add a simple SocketHandle struct, to create the socket once and reuse
it for multiple requests. This is still entirely internal API in
"nm-platform-utils.c".
2018-08-10 10:38:19 +02:00
Thomas Haller
29266e0086 platform/ethtool: split functions for ETHTOOL_GSTRINGS
ethtool_get_stringset() will be used later, independently.

Also, don't trust and ensure that the block of strings
returned by ETHTOOL_GSTRINGS are NUL terminated.
2018-08-10 10:38:19 +02:00
Francesco Giudici
356addb9e6 platform: allow to force the advertised auto-negotiation link value
This will only work for network devices supporting the BASE-T specification.
2018-06-15 14:19:50 +02:00
Thomas Haller
2a579f05fe platform: add NM_IP_CONFIG_SOURCE_IP6LL source type
We already have IP4LL and maybe should re-use that also for IPv6.
However, when adding the prefix route for IPv6 link local addresses,
we want to add it with protocol "kernel", unlike "user" for IPv4.

There is no strong reason for this. I don't think the protocol matters
much. But up to now kernel automatically adds this prefix route, so
as we are going to change that and let NetworkManager add it, keep the
protocol at "kernel".
2018-04-04 14:57:07 +02:00
Thomas Haller
e32839838e udev: drop libgudev in favor of libudev
libgudev is just a wrapper around libudev. We can
use libudev directly and drop the dependency for
libgudev.
2017-03-22 12:41:06 +01:00
Thomas Haller
22b7282d84 all: use "unsigned" instead of "unsigned int" 2017-03-14 11:26:29 +01:00
Lubomir Rintel
260563a7d9 all: use nm_utils_is_valid_iface_name() 2017-01-06 15:11:56 +01:00
Thomas Haller
87076d9345 platform: use wrappers for if_nametoindex() and if_indextoname() 2017-01-04 14:18:01 +01:00
Thomas Haller
e8d5a8356c platform: add wrappers for if_nametoindex() and if_indextoname() 2017-01-04 14:18:01 +01:00
Thomas Haller
d32fb8158b platform: avoid copying arguments for nmp_utils_ethtool_get_driver_info()
We call nmp_utils_ethtool_get_driver_info() twice when receiving a
netlink message, but we don't need a clone of the string values.
Instead, expose a data structure that should be stack allocated
by the caller.
2016-12-13 11:26:59 +01:00
Thomas Haller
16ad046c87 platform: remove unused nmp_utils_device_exists() util 2016-12-13 11:26:59 +01:00
Thomas Haller
3641178508 platform: lookup ifname for ethtool/mii ioctl immediately before use
The ioctl APIs ethtool/mii require an interface ifname. That is inherrently
racy as interfaces can be renamed. This cannot be fixed, we can only
minimize the time between verifying the ifname and calling ioctl.

We already had problems with that when ethtool would access an interface
by name that didn't exists. See commit ab41c13b06 .
Checking for an existing interface only helps avoiding races when an interface
gets deleted. It does not help against renaming.

Go one step further, and instead of checking whether such an ifname
exists, try to get the ifname based on the ifindex immediately before
we need it.

This brings an additional overhead for each ethtool access.
2016-12-13 11:26:59 +01:00
Thomas Haller
4bdee37771 all: use O_CLOEXEC for file descriptors 2016-12-13 11:26:59 +01:00
Thomas Haller
76876e896c platform: refactor nmp_utils_sysctl_open_netdir()
- use nm_auto_close cleanup attribute
- optionally, return the found ifname
- don't stat "phy80211". If such an entity can be opened,
  just assume it's a directory.
2016-12-13 11:26:58 +01:00
Kai-Heng Feng
713c74f6e4 platform: add a new function nmp_utils_open_sysctl()
A race condition may happen when NetworkManager opens sysfs and udev
renames interface name at the same time. Thomas Haller provides a new
function [1] which can avoid the race condition when opening sysfs.

This patch is a direct copy from [1].

[1] https://mail.gnome.org/archives/networkmanager-list/2016-December/msg00004.html

Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
2016-12-13 11:26:58 +01:00
Thomas Haller
d5a743a619 core: merge NM_PLATFORM_LINK_DUPLEX_UNSET and UNKNOWN
They have basically the same use, except that certain places handled
one but not the other.
2016-11-22 15:24:47 +01:00
Francesco Giudici
ab0954b0e5 platform: add APIs to allow link negotiation management
Added platform functions to retrieve device link mode status and to
switch from auto to manual link negotiation:
nm_platform_ethtool_get_link_settings
nm_platform_ethtool_set_link_settings
2016-11-22 15:24:47 +01:00
Lubomir Rintel
44fca246a7 rdisc: rename to ndisc
We'll soon not only do the router discovery, but announce ourselves as a
reouter. "Neighbor discovery" sounds to be a more appropriate name for
the class than "Router discovery".
2016-11-09 17:16:47 +01:00
Thomas Haller
a4a75b638f platform: refactor comparing for all-zero,all-ones MAC address in nmp_utils_ethtool_get_permanent_address()
Don't like the static fields.

Also, don't assert against return values from the ethtool call.
And check that the length is positive.
2016-05-24 16:01:59 +02:00
Thomas Haller
f8fb670c6f platform: declare nmp_utils_ip_config_source_*() functions as const 2016-05-16 13:16:49 +02:00
Thomas Haller
4c2410bc92 platform: extend NMIPConfigSource to preserve the rtm_protocol field
For addresses (NMPlatformIPAddress) the @addr_source field is ignored
on a platform level. That is, all addresses inside the platform cache
have this value set to NM_IP_CONFIG_SOURCE_KERNEL. Maybe, for that reason,
the source should not be a part of the NMPlatformIPAddress structure, but
it is convenient for users to piggy back the source inside the platform
address structure.

For routes, the source is stored in NMPlatformIPRoute's @rt_source
field. When adding a route to kernel, we set the @rtm_protocol of the
route depending on the source. However, we want to map different source
values to the same protocol value.

On the other hand, when kernel sends us a route that gets put inside
the cache, we must preserve the protocol value and must not map
different protocol values to the same source.
The reason is, that a user can add two routes that only differ by
@rtm_protocol. In that sense, the @rtm_protocol fields is part of the
unique ID of a kernel route, and thus different values must map to
different sources.

Fix this, by extending the range of NMIPConfigSource to contain
a range of protocol fields.
2016-04-28 12:53:21 +02:00
Thomas Haller
e26fcce0f8 platform: refactor marking cloned routes in platform
We handle cloned routes (that have rtm_flags RTM_F_CLONED) differently.
We used to mark such routes by hacking NMIPConfigSource to have a special
value. No longer do this, because it mixes different concepts.

Note that the rt_cloned filed fits into a hole in the aligment
of NMPlatformIPRoute. Thus there is almost no overhead to this
change.
2016-04-28 12:53:21 +02:00
Thomas Haller
9e83383223 platform: add nmp_utils_ip_config_source_to_string()
Expose nmp_utils_ip_config_source_to_string() in the header file and
implement it via NM_UTILS_ENUM2STR_DEFINE().
2016-04-28 12:53:21 +02:00
Thomas Haller
198baca830 platform: expose nmp_utils_ip_config_source_to/from_rtprot()
Will be used also from the tests.
2016-04-11 11:26:37 +02:00
Thomas Haller
6165df788d core: move simple utils function from "nm-platform-utils.h"
Most functions defined in "nm-platform-utils.h" perform a lookup
of link properties, for example via ethtool or sysfs. Those functions
depend on the system configuration, such as the current network namespace.

Move the simple helper functions away to "nm-core-internal.h", so that
all remaining functions from "nm-platform-utils.h" are really related to
somthing that interacts with the system/kernel.
2016-03-07 11:49:52 +01:00
Thomas Haller
0e90f1ba83 platform: add and use nm_utils_ifname_cpy() helper
Coverity complains rightly about "strncpy (dst, ifname, IFNAMSIZ)"
because it might leave @dst non-NULL-terminated, in case @ifname
is too long (which already would be a bug in the first place).

Replace the strcpy() uses by a new helper nm_utils_ifname_cpy()
that asserts against valid arguments.
2016-03-07 11:36:57 +01:00
Thomas Haller
adb56d137e core: split "nm-core-utils.h" out of "NetworkManagerUtils.h"
"NetworkManagerUtils.h" contains a bunch of helper tools for core
daemon ("src/").

Unfortunately, it has dependencies to other parts of core,
such as "nm-device.h" and "nm-platform.h". Split out a part
of tools that are independent so that they can be used without
dragging in other dependencies.

"nm-core-utils.h" should only use libnm-core, "nm-logging.h"
and shared.

"NetworkManagerUtils.h" should provide all "nm-core-utils.h" and
possibly other utilities that have larger dependencies.
2016-03-01 12:42:42 +01:00
Thomas Haller
328c733a6a platform: expose nmp_utils_ip4_address_is_link_local() function 2016-02-18 20:21:27 +01:00
Thomas Haller
e663b88c59 all/trivial: rename STRLEN() macro to NM_STRLEN()
We should not have defines/macros in header files without a nm/NM
prefix. STRLEN() was one of the few offenders.

https://mail.gnome.org/archives/networkmanager-list/2016-February/msg00048.html
2016-02-14 11:34:42 +01:00
Dan Williams
d442dcd174 platform: ignore permanent MAC addresses of all ones (FF:FF:FF:FF:FF:FF)
Drivers are stupid, and just like the platform ignores an all zeros
permanent address, so should it ignore all ones.

NetworkManager[509]: <debug> [1453743778.854919] [devices/nm-device.c:8885] nm_device_update_hw_address(): [0x190370] (eth0): hardware address now 86:18:52:xx:xx:xx
NetworkManager[509]: <debug> [1453743778.855438] [devices/nm-device.c:9138] constructed(): [0x190370] (eth0): read initial MAC address 86:18:52:xx:xx:xx
NetworkManager[509]: <debug> [1453743778.861602] [devices/nm-device.c:9148] constructed(): [0x190370] (eth0): read permanent MAC address FF:FF:FF:FF:FF:FF
2016-01-29 17:37:39 -06:00
Beniamino Galvani
e587dcb16e wake-on-lan: add option to keep existing settings
Add a new 'ignore' option to NMSettingWired.wake-on-lan which disables
management of wake-on-lan by NetworkManager (i.e. the pre-existing
option will not be touched). Also, change the default behavior to be
'ignore' instead of 'disabled'.

https://bugzilla.gnome.org/show_bug.cgi?id=755182
2015-10-16 17:11:26 +02:00
Thomas Haller
2733aacd64 platform: don't accept 00:00:00:00:00:00 as valid permanent address
In nmp_utils_ethtool_get_permanent_address(), don' accept a permanent
address of all zeros.

https://bugzilla.redhat.com/show_bug.cgi?id=1264024
2015-09-18 13:29:34 +02:00
Thomas Haller
2e66aea123 platform: stack-allocate request data for nmp_utils_ethtool_get_permanent_address() 2015-09-18 13:29:34 +02:00