Commit graph

11557 commits

Author SHA1 Message Date
Thomas Haller
c6c6295a96 platform: refactor NMPNetns avoiding global variable
Avoid accessing the global variable @_netns_stack (formerly @netns_stack)
directly. Access it once when needed, and pass it on as parameter.
2019-02-05 08:18:09 +01:00
Thomas Haller
12df49f8ab platform: make NMPNetns thread-safe
NMPNetns instances are immutable, hence they can be easily shared
between threads. All we need, is that the stack of namespaces is
thread-local.

Also note that NMPNetns uses almost no other API, except some bits from
"shared/nm-utils/" and nm-logging. These parts are already supposed to
be thread-safe.

The only complications is that when the thread exits, we need to
destroy the NMPNetns instances. That is especially important because
they hold file descriptors. This is accomplished using pthread's
thread-specific data. An alternative would be C11 threads' tss_create(),
but not all systems that we run against support that yet. This means,
we need to link with pthreads, but we already do that anyway.
Note that glib also requires pthreads. So, we don't get an additional
dependency here.
2019-02-05 08:18:08 +01:00
Thomas Haller
fcfd4f4ff2 logging: make nm-logging thread-safe
NetworkManager is single-threaded and uses a mainloop.

However, sometimes we may need multiple threads. For example, we will
need to write sysctl values asynchronously, using the glib thread-pool.
For that to work, we also need to switch the network-namespace of the
thread-pool thread. We want to use NMPNetns for that. Hence it's better
to have NMPNetns thread-safe, instead of coming up with a duplicate
implementation. But NMPNetns may want to log, so we also need nm-logging
thread-safe.

In general, code under "shared/nm-utils" and nm-logging should be usable
from multiple threads. It's simpler to make this code thread-safe than
re-implementing it. Also, it's a bad limitation to be unable to log
from other threads. If there is an error, the best we can often do is to
log about it.

Make nm-logging thread-safe. Actually, we only need to be able to log
from multiple threads. We don't need to setup or configure logging from
multiple threads. This restriction allows us to access logging from the
main-thread without any thread-synchronization (because all changes in
the logging setup are also done from the main-thread).

So, while logging from other threads requires a mutex, logging from the
main-thread is lock-free.
2019-02-05 08:18:08 +01:00
Thomas Haller
834c092b51 logging: avoid accessing global data from helper functions
We need to see where we modify/access global data. Instead of letting
helper functions access global data, pass it as arguments.
2019-02-05 08:18:08 +01:00
Thomas Haller
729feb0a93 logging: refactor and merge early logging initialization
Instead of having two functions nm_logging_set_syslog_identifier()
and nm_logging_set_prefix(), merge them.

They must both be called at earliest point and together. No point
in giving them the appearance that they could be called any time.
2019-02-05 08:18:08 +01:00
Thomas Haller
83338428d9 logging: move global "logging_domains_to_string" variable
This variable has other requirements for multi-threaded access (it will
only be accessible from the main-thread). Move it to a separate global
variable to make that clearer.
2019-02-05 08:18:08 +01:00
Thomas Haller
5e2202f41f logging: refactor globals in "nm-logging.c" to see where global gets modified
The distinction between only reading static data and modifying it,
is important when making nm-logging thread-safe.

This change should make it easier to find the places where we modify
data.
2019-02-05 08:18:08 +01:00
Thomas Haller
db2d6a1808 logging: cleanup type definition and global variables
First define types, then declare global variables.

Reorder the code.
2019-02-05 08:18:07 +01:00
Thomas Haller
eea11faf9a logging: split out enum type definition for LogBackend 2019-02-05 08:18:07 +01:00
Thomas Haller
8dcc3cd51a logging: split out @level_desc and @domain_desc variables from global data
@level_desc and @domain_desc are two immutable arrays with information
about logging levels and logging domains. Since they are immutable and
intialized from the start, they are pretty trival w.r.t. tread-safety and
general maintainability (code readability).

Refactor them to be separate variables.
2019-02-05 08:18:07 +01:00
Thomas Haller
ba1bf0390d logging: make _nm_logging_clear_platform_logging_cache() a regular function
Previously, _nm_logging_clear_platform_logging_cache was an extern variable,
and NMLinuxPlatform would set it to a function pointer at certain points.

That's unnecessary complex, also when trying to make nm-logging thread-safe,
it's just more global variables that need to be considered. Don't do it
that way, but just link in a regular function.
2019-02-05 08:18:07 +01:00
Thomas Haller
953dd4ac49 core: drop unused <pthread.h> include from src/main.c 2019-02-05 08:18:06 +01:00
Lubomir Rintel
ef6d461b7f platform/linux: fix setting of IFA_ADDRESS without a peer
Since commit 9ecdba316 ('platform: create netlink messages directly
without libnl-route-3') we're unconditionally setting IFA_ADDRESS to
the peer address, even if there's no peer and it's all zeroes.

The kernel actually stopped caring somewhere around commit caeaba790
('ipv6: add support of peer address') in v3.10, but Ubuntu Touch likes
to run Android's v3.4 on some poorly supported hardware.

Fixes: 9ecdba316c

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/77
2019-02-05 07:11:12 +01:00
Thomas Haller
866ac505a8 libnm,core: various cleanups of _nm_connection_for_each_secret()
- use cleanup attribute to free memory

- return floating reference from _nm_connection_for_each_secret().
  It's more idiomatic that a function that constructs a variant and
  returns it, returns a floating variant.
2019-02-04 20:15:20 +01:00
Thomas Haller
79a0238c5e libnm,core: move _nm_connection_for_each_secret() from core to libnm-core
_nm_connection_for_each_secret() (formerly for_each_secret()) and
_nm_connection_find_secret() (formerly find_secret()) operate on a
GVariant of secrets. For that, they implement certain assumptions
of how to handle secrets. For example, it must special-case VPN settings,
because there is no generic abstraction to handle regular secret and VPN
secrets the same.

Such special casing should only be done in libnm-core, at one place.

Move the code to libnm-core as internal API.
2019-02-04 20:15:20 +01:00
Thomas Haller
4ea6c83e9b settings: fix handling of VPN secrets in for_each_secret()
nm_setting_get_secret_flags() looks whether we have a suitable "-flags"
data value, or whether we have a secret with that name.

In fact, we know this is a valid secret-name. Even if there are no secret-flags
and the secret (currently) does not exists. We shall not care about the
return value.

Note that nm_setting_get_secret_flags() also for non-secrets will set
the flags to "NONE", which is just what we need.
2019-02-04 20:15:20 +01:00
Thomas Haller
5eac241578 settings: fix for_each_secret() to check variant type of VPN secrets
We cannot just blindly assume that the variant is of the right type
to iterate over it.
2019-02-04 20:15:20 +01:00
Thomas Haller
cabc1ddca5 settings: fix leaking variant in for_each_secret()
Fixes: df6706813a
2019-02-04 20:15:20 +01:00
Thomas Haller
c7b3c23af2 ifcfg-rh/tests: avoid duplicate const warning for NO_EXPECTED
../src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c:126:19: warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier]
     static const char const NO_EXPECTED[1];
                       ^~~~~

Fixes: f04bf45e84
2019-02-04 16:55:43 +01:00
Beniamino Galvani
797eab2f6b vpn: add route to vpn gw when parent has a default device route
When the parent device has a device default route (i.e. without
gateway) and we establish a VPN on top of it, 'ip route get' for the
VPN gateway returns a device route, which is the same result we get
for an unreachable VPN gateway. However it is necessary to add the
route to the gateway or otherwise it will possibly become unreachable
once the VPN gets activated.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/93
2019-02-04 11:07:02 +01:00
Thomas Haller
c77871e5e9 all: avoid bogus compiler warning about uninitialized variable
With LTO and optimizations, gcc issues several bogus
"maybe-uninitialized" warnings.

Work-around them by initializing the variables.
2019-02-04 10:55:25 +01:00
Thomas Haller
43a12462e0 platform/tests: increase timeout for platform tests
Seems 180 seconds is still not enough for "/link/create-many-links/1000"
tests on gitlab-CI.
2019-02-04 10:52:19 +01:00
Thomas Haller
09090f2669 wifi-p2p: rename Wi-Fi P2P
After renaming the files, also rename all the content
to follow the "Wi-Fi P2P" naming scheme.
2019-02-01 17:02:57 +01:00
Thomas Haller
0420fa1f2c wifi-p2p: rename files for consistent Wi-Fi P2P naming
We named the types inconsistently:

  - "p2p-wireless" ("libnm-core/nm-setting-p2p-wireless.h")

  - "p2p" ("libnm/nm-p2p-peer.h")

  - "p2p-wifi" ("src/devices/wifi/nm-device-p2p-wifi.h")

It seems to me, "libnm/nm-p2p-peer.h" should be qualified with a "Wi-Fi"
specific name. It's not just peer-to-peer, it's Wi-Fi P2P.
Yes, there is an inconsistency now, because there is already
"libnm/nm-access-point.h".

It seems to me (from looking at the internet), that the name "Wi-Fi P2P"
is more common than "P2P Wi-Fi" -- although both are used. There is also
the name "Wi-Fi Direct". But it's not clear which name should be
preferred here, so stick to "Wi-Fi P2P".

In this first commit only rename the files. The following commit will
rename the content.
2019-02-01 17:02:57 +01:00
Thomas Haller
c8204377d6 core/device-p2p-wifi: drop unused code
If this is going to be implemented, revert the patch.
2019-02-01 17:02:57 +01:00
Thomas Haller
37da2d8a06 core/device-p2p-wifi/trival: move code
Have the class_init() function at the bottom.
2019-02-01 17:02:57 +01:00
Thomas Haller
43aa288fd8 core/p2p-wifi: various minor cleanups 2019-02-01 17:02:57 +01:00
Thomas Haller
4ac6c7fdf1 all/trivial: whitespace 2019-02-01 17:02:57 +01:00
Thomas Haller
477e91d753 connectivity: don't cache HTTP response for comparing connectivity response
We don't need to remember (and compare) all the bytes that we received.
We can just compare them right away, and remember how many good bytes
we received.
2019-01-31 11:33:44 +01:00
Thomas Haller
7807ffff83 connectivity: fix handling of no-response for captive portal detection
Since we only compare that the HTTP response starts with the expected
response, we need to handle the empty expected response specially
(because, every response has "" as prefix).

So now if connectivity.response is set to "" (empty) we accept:

- HTTP status code 204. We ignore and accept any extra data that we
  might receive.

- HTTP status code 200 and an empty (or no) body.
2019-01-31 11:33:44 +01:00
Benjamin Berg
5ae4245be2 manager: Fix GVariant format strings for AddAndActivate2 return value
AddAndActivate2 returns an empty a{sv} dictionary for extensibility. The
format strings to create the methods return value were slightly wrong,
causing assertion failures.

Fixes: fbb038af5e

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/73
2019-01-29 13:30:14 +01:00
Thomas Haller
7d5da12e8e wifi-p2p: don't assert for pending action 'waiting-for-supplicant' in nm_device_p2p_wifi_set_mgmt_iface()
<info>  [1548688998.8282] device (wlan0): supplicant interface state: starting -> ready
 <debug> [1548688998.8282] device[0x55bd55f19f30] (p2p-dev-wlan0): P2P: Releasing WPA supplicant interfaces.
 <debug> [1548688998.8282] device[0x55bd55f19f30] (p2p-dev-wlan0): P2P: WPA supplicant management interface changed to /fi/w1/wpa>
 <warn>  [1548688998.8282] device (p2p-dev-wlan0): remove_pending_action (0): 'waiting-for-supplicant' not pending
 file src/devices/nm-device.c: line 14134 (nm_device_remove_pending_action): should not be reached

   #0  0x00007f2c58dad1e5 n/a (libglib-2.0.so.0)
   #1  0x00007f2c58dae51d g_logv (libglib-2.0.so.0)
   #2  0x00007f2c58dae6f3 g_log (libglib-2.0.so.0)
   #3  0x000055bd55246104 nm_device_remove_pending_action (NetworkManager)
   #4  0x00007f2c487c4864 nm_device_p2p_wifi_set_mgmt_iface (libnm-device-plugin-wifi.so)
   #5  0x00007f2c58e94c73 n/a (libgobject-2.0.so.0)
   #6  0x000055bd55233112 constructor (NetworkManager)
   #7  0x00007f2c58e94e8b n/a (libgobject-2.0.so.0)
   #8  0x00007f2c58e96fde g_object_new_valist (libgobject-2.0.so.0)
   #9  0x00007f2c58e9733d g_object_new (libgobject-2.0.so.0)
   #10 0x00007f2c487c4a65 nm_device_p2p_wifi_new (libnm-device-plugin-wifi.so)
   #11 0x00007f2c487c6655 recheck_p2p_availability (libnm-device-plugin-wifi.so)
   #12 0x00007f2c487c9119 supplicant_iface_state_cb (libnm-device-plugin-wifi.so)
   #13 0x00007f2c58525ace ffi_call_unix64 (libffi.so.6)
   #14 0x00007f2c5852548f ffi_call (libffi.so.6)
   #15 0x00007f2c58e903a6 g_cclosure_marshal_generic_va (libgobject-2.0.so.0)
   #16 0x00007f2c58e8f636 n/a (libgobject-2.0.so.0)
   #17 0x00007f2c58eabb01 g_signal_emit_valist (libgobject-2.0.so.0)

Fixes: 00e64d1332
2019-01-28 16:43:57 +01:00
Benjamin Berg
dd0c59c468 core/devices: Add DBus methods to start/stop a P2P find
By default the find will run for 30s. This can be increased or decreased
in the range of 1-600s by setting "Timeout" in the options parameter.
2019-01-27 23:45:12 +01:00
Benjamin Berg
959886892a core/devices: Automatically create P2P device for wifi devices
If a wifi device supports P2P mode, then create a further P2P device for
it automatically.
2019-01-27 23:45:12 +01:00
Benjamin Berg
00e64d1332 core/devices: Add P2P Wifi device and peer tracking
This only adds the new device type and simple peer list handling.
2019-01-27 23:45:12 +01:00
Lubomir Rintel
c7d6e55ed7 ppp-manager: fix a typo in a debugging statement
Discovered by GCC 9:

  src/ppp/nm-ppp-manager.c: In function ‘_ppp_manager_start’:
  ./src/nm-logging.h:59:9: error: ‘%s’ directive argument is null [-Werror=format-overflow=]

Fixes: 35d9169c3c
2019-01-27 17:24:59 +01:00
Rafael Fontenelle
d81e10942f all: fix misspellings
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/64
2019-01-24 17:19:44 +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
32749cea99 platform: support missing endpoint in _wireguard_create_change_nlmsgs() 2019-01-22 16:30:23 +01:00
Thomas Haller
977b033d12 platform: improve API of sockaddr handling
Add cmp/hash functions that correctly honor the well known fields, instead
of doing memcmp/memcpy of the entire sockaddr structure.

Also, move the set function to nm_sock_addr_union_cpy() and
nm_sock_addr_union_cpy_untrusted(). This also gets it right
to ensure all bytes of the union are initialized (to zero).
2019-01-22 16:30:23 +01:00
Thomas Haller
c4eadb709c initrd/trivial: fix whitespace 2019-01-21 14:18:54 +01:00
Lubomir Rintel
125b9a5a5d initrd: make the default connection activatable on multiple devices
The ip=dhcp (without a device name given) and such should activate all
possible devices.

https://github.com/NetworkManager/NetworkManager/pull/284
2019-01-21 13:00:04 +01:00
Beniamino Galvani
58c4cd9cc9 supplicant: don't set PMF when the supplicant doesn't support it
When the supplicant does not support PMF we wrongly set
'ieee80211w=0', but since the option is not recognized the connection
fails. Don't set it when unsupported.

Fixes: a9ab50efb1
2019-01-17 09:40:29 +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
617bdbd8c2 all/trivial: rename NM_UTILS_LOOKUP_STR() to have "_A" suffix
NM_UTILS_LOOKUP_STR() uses alloca(). Partly to avoid the overhead of
malloc(), but more important because it's convenient to use. It does
not require to declare a varible to manage the lifetime of the heap
allocation.

It's quite safe, because the stack allocation is of a fixed size of only
a few bytes. Overall, I think the convenience that we get (resulting in
simpler code) outweighs the danger of stack allocation in this case. It's
still worth it.
However, as it uses alloca(), it still must not be used inside a (unbound)
loop and it is obviously a macro.

Rename the macros to have a _A() suffix. This should make the
peculiarities more apparent.
2019-01-15 09:52:01 +01:00
Thomas Haller
e18ff51d4f tests: don't use alloca() in tests
The only purpose of using alloca() to avoid the overhead of heap-allocation
and possible save a line in source code for managing/freeing the heap allocation.

For tests we don't care about performance, and (in this case)
the code does not get any shorter.

Avoid alloca() in tests, because alloca() is something to search for
when reviewing code for stack overflows. No need to have such false
positives show up in tests.
2019-01-15 09:52:01 +01:00
Thomas Haller
694533f529 shared: add nm_utils_strbuf_append_bin() helper
Add a version of nm_utils_strbuf_append_*() that does not care
about NUL terminate strings, but accept any binary data. That makes
it useful for writing a binary buffer.
2019-01-14 16:40:39 +01:00
Thomas Haller
fbb038af5e all: return output dictionary from "AddAndActivate2"
Add a "a{sv}" output argument to "AddAndActivate2" D-Bus API.
"AddAndActivate2" replaces "AddAndActivate" with more options.
It also has a dictionary argument to be forward compatible so that we
hopefully won't need an "AddAndActivate3". However, it lacked a similar
output dictionary. Add it for future extensibility. I think this is
really to workaround a shortcoming of D-Bus, which does provide strong
typing and type information about its API, but does not allow to extend
an existing API in a backward compatible manner. So we either resort to
Method(), Method2(), Method3() variants, or a catch-all variant with a
generic "a{sv}" input/output argument.

In libnm, rename "nm_client_add_and_activate_connection_options()" to
"nm_client_add_and_activate_connection2()". I think libnm API should have
an obvious correspondence with D-Bus API. Or stated differently, if
"AddAndActivateOptions" would be a better name, then the D-Bus API should
be renamed. We should prefer one name over the other, but regardless
of which is preferred, the naming for D-Bus and libnm API should
correspond.

In this case, I do think that AddAndActivate2() is a better name than
AddAndActivateOptions(). Hence I rename the libnm API.

Also, unless necessary, let libnm still call "AddAndActivate" instead of
"AddAndActivate2". Our backward compatibility works the way that libnm
requires a server version at least as new as itself. As such, libnm
theoretically could assume that server version is new enough to support
"AddAndActivate2" and could always use the more powerful variant.
However, we don't need to break compatibility intentionally and for
little gain. Here, it's easy to let libnm also handle old server API, by
continuing to use "AddAndActivate" for nm_client_add_and_activate_connection().
Note that during package update, we don't restart the currently running
NetworkManager instance. In such a scenario, it can easily happen that
nmcli/libnm is newer than the server version. Let's try a bit harder
to not break that.

Changes as discussed in [1].

[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37#note_79876
2019-01-14 11:56:18 +01:00
Thomas Haller
3ae5c9d595 core: cleanup error path in activation_add_done()
Don't return success from a nested code path. Handle all errors
first, and return early. Well, we cannot really return right away
because we need to handle the failure. So, at least, check for errors
and "goto fail".
2019-01-14 11:55:17 +01:00