Commit graph

21637 commits

Author SHA1 Message Date
Thomas Haller
da05a6b5e5 all: merge branch 'benzea/dbus-service-specific-connection'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/37
2018-11-19 11:00:37 +01:00
Thomas Haller
26eaca89b8 libnm: drop "_async" suffix from nm_client_add_and_activate_connection_options()
Synchronous D-Bus calls seems harmful to me, such API should not be
added to libnm. As such, all API is by default and preferably "_async".

Don't add an "_async" suffix. While we are not consistent in libnm about
this, I think for new code we should.
2018-11-19 10:53:39 +01:00
Thomas Haller
1d9a808a58 libnm: add missing NM_AVAILABLE_IN_1_16 macros for new API 2018-11-18 17:59:31 +01:00
Thomas Haller
28c386df8a manager: prefer nm_streq over strcmp in impl_manager_add_and_activate_connection()
- use nm_streq() instead of g_strcmp0(). I think streq() is easier
  to understand.

- the strings that are checked here must never be %NULL, because they come
  from string variants. Use nm_streq() instead of nm_streq0() or g_strcmp0().

- don't add a "." to the GError messages. GError messages are commonly
  embedded in a larger message, and shoult not themself contain the dot.
2018-11-18 11:59:47 +01:00
Thomas Haller
bc23dc8ff0 manager: fix checking for bind-lifetime setting in add-and-activate
Previously, @bind_lifetime was a string. While parsing the @options, we
would set the string to the content of the parsed GVariant. Note that
the GVariant is unrefed before we access @bind_lifetime, thus it's
not guaranteed that it will still exist.

Arguably, the string GVariant's lifetime is tied to the @options
dictionary, so indeed it lives long enough. But that is not-obviously
the case.

Fix that by using a boolean instead. Also, rename @bind_lifetime to
@bind_dbus_client.
2018-11-18 11:59:47 +01:00
Thomas Haller
6f28f4b661 manager: allow add-and-activate option "bind" with non-volatile profiles
For one, there was a bug here: we cannot "goto error" without setting
the @error variable.

Anyway, restricting "bind" "dbus-client" only to profiles that are
"persist" mode "volatile" seems wrong. The "bind" option as it is,
limits the lifetime of the active-connection. This has no direct relation
with the lifetime of the setting-connection. Indeed, if the
settings-connection's lifetime is itself set to "volatile", then
it will indeed go away with the active-connection. However, these
two concepts are not strictly related.

In the future, we might add an option to limite the lifetime of
a settings-connection to a D-Bus client ("bind-setting"). Possibly
we should thus rename "bind" to "bind-activation", to make the
distinction clearer.
2018-11-18 11:59:47 +01:00
Thomas Haller
f10f019982 policy: don't check for valid error in active_connection_keep_alive_changed()
Most (not all) functions that can fail and report the reason with
an GError are required to set the error if they fail. It's a bug
to claim to fail without returning the GError reason.

Hence, our callers usually don't check whether a GError is present but
just access it.

Likewise, for better or worse, our GError codes are often not meaningful
(unless explicitly documented). Meaning, logging the error code number
is not helpful. Instead, error messages should be written in a manner
that one can find the source code location where it happened.

Also, return-early to reduce the indentation level of the code.

Also, drop the code comment. It seems to just describe what is obviously
visible by reading the source. It doesn't explain much beside that the
"doesn't have a reason", but not really why.
2018-11-17 13:38:15 +01:00
Thomas Haller
6b79af28d6 keep-alive: minor cleanup of nm_keep_alive_set_dbus_client_watch()
- always issue a _notify_alive(), just to be sure. At least
  in case where we clear a dbus-client watch, the alive state
  could change.

- avoid the logging in cleanup_dbus_watch(), if there is nothing
  to cleanup.
2018-11-17 13:29:40 +01:00
Thomas Haller
3baf56b474 keep-alive: cleanup tracking visible state of connection
- in nm_keep_alive_set_settings_connection_watch_visible(), abort
  early when setting the same connection again (or %NULL again).

- nm_keep_alive_set_settings_connection_watch_visible() would (already
  before) correctly disconnect the signal handler from the previous
  connection.
  As we anyway do explict disconnects, avoid the overhead of a weak
  pointer with g_signal_connect_object(). Just reuse the same
  setter to disconnect the signal in dispose().

- fix leaking priv->connection in nm_keep_alive_set_settings_connection_watch_visible().

- use g_signal_handlers_disconnect_by_func(), to be more specific about
  which signal we want to disconnect.
2018-11-17 13:13:38 +01:00
Thomas Haller
be91d1cc4e keep-alive: cache the alive-state and only emit the signal when it changed
The alive state is composed from various parts, let's only emit
a _notify (self, PROP_ALIVE) when it actually changes.

For that, cache the alive state and let _notify_alive() determine
whether it changed and possibly emit the signal.
2018-11-17 13:11:38 +01:00
Thomas Haller
58923de4e4 keep-alive: various style fixes
Some trivial changes:

- move nm_keep_alive_new() after nm_keep_alive_init(), so that the
  functions that initialize the instance are beside each other.
- prefer nm_streq*() over strcmp().
- wrap some lines.
- remove some empty lines.
2018-11-17 12:50:58 +01:00
Thomas Haller
7842a58055 keep-alive: drop unused error argument 2018-11-17 12:43:25 +01:00
Benjamin Berg
00236ef977 libnm: Add support to pass options to AddAndActivateConnection
This adds the new methods nm_client_add_and_activate_connection_options_*
and ports the existing methods to use the new AddAndActivateConnection2
call rather than AddAndActivateConnection, allowing further parameters
to be passed in.
2018-11-17 12:15:40 +01:00
Benjamin Berg
eb883e34a5 core: Add option to AddAndActivateConnection2 to bind the lifetime
This allows binding the lifetime of the created connection to the
existance of the requesting dbus client. This feature is useful if one
has a service specific connection (e.g. P2P wireless) which will not be
useful without the specific service.

This is simply a mechanism to ensure proper connection cleanup if the
requesting service has a failure.
2018-11-17 12:15:40 +01:00
Benjamin Berg
9cef6483dc core: Add persist option to AddAndActivateConnection2
This option allows setting the rules for how long the connection should
be stored. Valid values are "disk" (the default), "memory" and
"volatile". If "memory" or "volatile" is selected, the connection will
not be saved to disk and with "volatile" it will be automatically
removed when it is deactivated again.
2018-11-17 12:15:40 +01:00
Benjamin Berg
43c19d755a core: Add an AddAndActivateConnection2 routine with options parameter
This adds a new routine to be able to handle an arbitrary set of further
options for AddAndActivateConnection. Note that no options are accepted
for now.
2018-11-17 12:15:40 +01:00
Benjamin Berg
37e8c53eee core: Introduce helper class to track connection keep alive
For P2P connections it makes sense to bind the connection to the status
of the operation that is being done. One example is that a wifi display
(miracast) P2P connection should be shut down when streaming fails for
some reason.

This new helper class allows binding a connection to the presence of a
DBus path meaning that it will be torn down if the process disappears.
2018-11-17 12:15:40 +01:00
garywill
faba9b12de po: update zh_CN.po fix "Infra" translation
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/48
2018-11-16 08:07:58 +01:00
Thomas Haller
aae6846d20 device: ignore "carrier-wait" when device is already activated
nm_device_has_pending_action_reason() marks the device as busy, which in
turn delays "startup-complete" and NetworkManager-wait-online.service.

A device which has no carrier but is otherwise in activated state, is
clearly ready. I didn't test this, but I presume that can easily be the
case with static IP configuration (which can activate without the device
having carrier).
2018-11-15 15:36:49 +01:00
Benjamin Berg
e179202e47 systemd: fix crash by unrefing event sources before re-adding them
In certain cases the timeouts may not have been unref'ed before they
need to be re-added. Add the appropriate unref calls to ensure we don't
register the timeout multiple times.

This fixes possible cases where timeouts are triggered multiple times
and even on destroyed DHCPv6 clients.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/73
2018-11-15 14:06:59 +01:00
Beniamino Galvani
ca0c025486 build: dist initrd meson.build files
Fixes: b544f7243d

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/77
2018-11-15 09:25:11 +01:00
Thomas Haller
89bd19b0d7 man: fix typo in nmcli manual
Fixes: 17f9801e07
2018-11-14 18:26:07 +01:00
Francesco Giudici
2f2ad4d925 man: add an early reference to nmcli-examples in nmcli man page 2018-11-14 17:15:55 +01:00
Francesco Giudici
e3ea7245c3 man: add OTP-based VPN activation example 2018-11-14 17:15:50 +01:00
Thomas Haller
2799634082 dhcp: merge branch 'th/dhcp-client-id-mac-rh1640494'
https://github.com/NetworkManager/NetworkManager/pull/243
2018-11-14 08:15:42 +01:00
Thomas Haller
787f4b57cd dhcp: initialize hostname as construct-property
The hostname property is only initialized once, early on during
start. Move the initialization even earlier during object constructions.
This effectively makes the hostname an immutable property.

This also makes sense, because the hostname is used by IPv4 and
IPv6 DHCP instances alike.
2018-11-14 08:11:41 +01:00
Thomas Haller
e9630e7d57 core/trivial: add code comment about DHCP client-id/DUID 2018-11-13 19:09:34 +01:00
Thomas Haller
8861ac2976 dhcp: add "ipv4.dhcp-client-id=duid" setting
Add a new mode for the DHCPv4 client identifier.

"duid" is what the internal (systemd) DHCP client already does by
default. It is also the same as used by systemd-networkd's
"ClientIdentifier=duid" setting. What we still lack (compared to
networkd) are a way to overwrite IAID and the DUID.

Previously, this mode was used by the internal DHCP plugin
by default. However, it could not be explicitly configured.
In general, our default values should also be explicitly selectable.
Now the "duid" client identifier can also be used with the "dhclient"
plugin.
2018-11-13 19:09:34 +01:00
Thomas Haller
dfdd4e3bd3 dhcp: always require hwaddr in internal DHCP clint ip6_start()
Note how client_start() in NMDhcpManager already asserts
that we have a MAC address. It's always present, like
for the IPv6 case.
2018-11-13 19:09:34 +01:00
Thomas Haller
5ef93c3323 doc: add hint about ipv4.dhcp-client-id=stable 2018-11-13 19:09:34 +01:00
Thomas Haller
7ffbf71276 all: add "${MAC}" substituion for "connection.stable-id"
We already had "${DEVICE}" which uses the interface name.
In times of predictable interface naming, that works well.
It allows the user to generate IDs per device which don't
change when the hardware is replaced.

"${MAC}" is similar, except that is uses the permanent MAC
address of the device. The substitution results in the empty
word, if the device has no permanent MAC address (like software
devices).

The per-device substitutions "${DEVICE}" and "${MAC}" are especially
interesting with "connection.multi-connect=multiple".
2018-11-13 19:09:34 +01:00
Thomas Haller
ab314065b8 dhcp: cleanup error handling in internal DHCP client's start
- use nm_auto to return early when something goes wrong

- don't modify NMDhcpClient's state until the end, when it looks
  like we are (almost) started successfully.

- for IPv4, only attempt to load the lease if we actually are
  interested in the address. Also, reduce the scope of the lease
  variable, to the one place where we need it.
2018-11-13 19:09:34 +01:00
Thomas Haller
5b9bc174d1 dhcp: don't load IPv4 client-id from lease file
The client-id is something that we want to determine top-down.
Meaning, if the user specifies it via ipv4.dhcp-client-id, then it
should be used. If the user leaves it unspecified, we choose a
default stable client-id. For the internal DHCP plugin, this is
a node specific client-id based on

  - the predictable interface name
  - and /etc/machine-id

It's not clear, why we should allow specifying the client-id in
the lease file as a third source of configuration. It really pushes
the configuration first down (when we do DHCP without lease file),
to store an additional bit of configuration for future DHCP attempts.

If the machine-id or the interface-name changes, then so does the
default client-id. In this case, also "ipv4.dhcp-client-id=stable"
changes. It's fair to require that the user keeps the machine-id
stable, if the machine identity doesn't change.

Also, the lease files are stored in /var/lib/NetworkManager, which
is more volatile than /etc/machine-id. So, if we think that machine-id
and interface-name is not stable, why would we assume that we have
a suitable lease file?

Also, if you do:

   nmcli connection add con-name "$PROFILE" ... ipv4.dhcp-client-id ''
   nmcli connection up $PROFILE
   nmcli connection modify "$PROFILE" ipv4.dhcp-client-id mac
   nmcli connection up $PROFILE
   nmcli connection modify "$PROFILE" ipv4.dhcp-client-id ''
   nmcli connection up $PROFILE

wouldn't you expect that the original (default) client-id is used again?

Also, this works badly with global connection defaults in
NetworkManager.conf. If you configure a connection default, previously
already this would always force the client-id and overrule the lease.
That is reasonable, but in which case would you ever want to use
the client-id from the lease?
2018-11-13 19:09:34 +01:00
Thomas Haller
c3e7e6170d dhcp: cleanup initializing IPv4 client-id for internal DHCP
- if we leave the client-id of sd_dhcp_client unset, it will
  anyway generate a node-specific client-id (and may fail if
  "/etc/machine-id" is invalid).
  Anticipate that, and don't let the client-id unset. In case
  we have no client-id from configuration or lease, just generate
  the id ourself (using the same algorithm). The advantage is,
  that we know it upfront and can store the client-id in the
  NMDhcpClient instance. We no longer need to peel it out from
  the lease later.

- to generate the IPv4 client-id, we need a valid MAC address. Also,
  sd_dhcp_client needs a MAC address for dhcp_network_bind_raw_socket()
  as well. Just require that a MAC address is always needed. Likewise,
  we need a valid ifindex and ifname set.

- likewise for IPv6 and IPv4, cleanup detecting the arptype and
  checking MAC address length. sd_dhcp_client_set_mac() is overly
  strict at asserting input arguments, so we must validate them anyway.

- also, now that we always initialize the client-id when starting
  the DHCP client, there is no need to retroactively extract it
  again when we receive the first lease.
2018-11-13 19:09:34 +01:00
Thomas Haller
ce1cfd7232 dhcp/trivial: wrap lines in calling client_start()
A possible issue is that client_start() has about 136 arguments.
It doesn't get simpler by saving lines of code and writing them
all in the same line.

Wrap the lines.

While at it, use "FALSE" for "enforce_duid" argument, instead of "0".
It's a boolean.
2018-11-13 19:09:34 +01:00
Thomas Haller
d6d2b7296f dhcp: minor refactoring return paths in NMDhcpDhclient.get_duid() 2018-11-13 19:09:33 +01:00
Thomas Haller
b833d68d68 dhcp: use cleanup attribute for get_dhclient_leasefile() 2018-11-13 19:09:33 +01:00
Thomas Haller
7d55b1348b dhcp: don't pass duid to client ip6_start() and stop()
We don't do that for ip4_start() either. The duid/client-id
is stored inside the NMDhcpClient instance, and the function can
access it from there.

Maybe, it is often preferable to have stateless objects and not
relying on ip4_start() to obtain the client ID from the client's
state. However, the purpose of the NMDhcpClient object is to
hold state about DHCP. To simplify the complexity of objects that
inherrently have state, we should be careful about mutating the state.
It adds little additional complexity of only reading the state when
needed anyway. In fact, it adds complexity, because previously
it wasn't enough to check all callers of nm_dhcp_client_get_client_id()
to see where the client-id is used. Instead, one would also need to
follow the @duid argument several layers of the call stack.
2018-11-13 19:09:33 +01:00
Thomas Haller
cd9e418fbe dhcp: refactor nm_dhcp_dhclient_save_duid() to accept original DUID
There should be lower layers that are concerned with writing
and reading dhclient configuration files. It's wrong to
have a nm_dhcp_dhclient_save_duid() function which requires
the caller to pre-escape the string to write. The caller shouldn't
be concerned with the file format, that's why the function
is used in the first place.
2018-11-13 19:09:33 +01:00
Thomas Haller
7e341b73e0 dhcp: merge "duid" and "client_id" field in NMDhcpClient
We only used "client_id" for IPv4 and "duid" for IPv6. Merge them.

Another advantage is, that we can share the logging functionality
of _set_client_id().
2018-11-13 19:09:33 +01:00
Thomas Haller
025157d597 dhcp: drop unused nm_dhcp_dhclient_get_client_id_from_config_file()
Drop unused function.

Aside from that, dhclient configuration files support a very complex
syntax. The parser was very naive and insufficient in parsing such
files. It's good we can just drop it.
2018-11-13 19:09:33 +01:00
Thomas Haller
5411fb0cc6 dhcp: don't re-read DHCP client ID from configuration file for dhclient
Why would we do this? The configuration file we are reading back was
written by NetworkManager in the first place.

Maybe when assuming a connection after restart, this information could
be interesting. It however is not actually relevant.

Note how nm_dhcp_client_get_client_id() has only very few callers.

  - nm_device_spawn_iface_helper() in 'nm-device.c'. In this case,
    we either should use the client-id which we used when starting
    DHCP, or none at all.

  - ip4_start() in 'nm-dhcp-dhclient.c', but this is before starting
    DHCP client and before it was re-read from configuration file.

  - in "src/dhcp/nm-dhcp-systemd.c", but this has no effect for
    the dhclient plugin.
2018-11-13 19:09:33 +01:00
Thomas Haller
a55795772a dhcp: reimplement node-specific DHCP client-id generation from systemd
Our internal DHCP client (from systemd) defaults to a particular client ID.
It is currently exposed as nm_sd_utils_generate_default_dhcp_client_id()
and is based on the systemd implementation.

One problem with that is, that it internally looks up the interface name
with if_indextoname() and reads /etc/machine-id. Both makes it harder
for testing.

Another problem is, that this way of generating the client-id is
currently limited to internal client. Why? If you use dhclient plugin,
you may still want to use the same algorithm. Also, there is no explict
"ipv4.dhcp-client-id" mode to select this client-id (so that it could
be used in combination with "dhclient" plugin).
As such, this code will be useful also aside systemd DHCP plugin.
Hence, the function should not be obviously tied to systemd code.

The implementation is simple enough, and since we already have a
unit-test, refactor the code to our own implementation.
2018-11-13 19:09:33 +01:00
Thomas Haller
187d356198 dhcp: test systemd's default DHCP client identifier generation
Internal DHCP client generates a default client ID. For one,
we should ensure that this algorithm does not change without
us noticing, for example, when upgrading systemd code. Add
a test, that the generation algorithm works as we expect.

Also note, that the generation algorithm uses siphash24().
That means, siphash24() implementation also must not change
in the future, to ensure the client ID doesn't change. As we
patch systemd sources to use shared/c-siphash, this is not
obviously the case. Luckily c-siphash and systemd's siphash24 do
agree, so all is good. The test is here to ensure that.

Also, previously the generation algorithm is not exposed as a
function, sd_dhcp_client will just generate a client-id when
it needs it. However, later we want to know (and set) the client
id before starting DHCP and not leave it unspecified to an
implementation detail.

This patch only adds a unit-test for the existing DHCP client
ID generation to have something for comparison. In the next
commit this will change further.
2018-11-13 19:09:33 +01:00
Thomas Haller
50121ee028 core: cleanup generating DUID in nm-device.c
- use NMUuid type where appropriate.

- no error handling for generate_duid_from_machine_id().
  It cannot fail anymore.

- add thread-safety to generate_duid_from_machine_id() with
  double-checked locking.

- use unions for converting the sha256 digest to the target
  type.
2018-11-13 19:09:33 +01:00
Thomas Haller
c51e63feb6 core: pass boot-id to nm_utils_stable_id_parse()
For testing purpose, it's bad to let nm_utils_stable_id_parse()
directly access nm_utils_get_boot_id_str(). Instead, the function
should have no side-effects.

Since the boot-id is anyway cached, accessing it is cheap. Even
if it likely won't be needed.
2018-11-13 19:09:31 +01:00
Thomas Haller
581e1c3269 core: don't persist secret-key for tests
Tests might access the secret-key.

For CI builds we may very well build NM as root and also run
unit tests. In such a situation it's bad to persist the secret
key. For example, the SELinux label may be wrong, and subsequently
starting NetworkManager may cause errors. Avoid persisting the secret
key for tests.
2018-11-13 19:08:26 +01:00
Thomas Haller
8308311264 core: refactor loading machine-id and cache it
Previously, whenever we needed /etc/machine-id we would re-load it
from file. The are 3 downsides of that:

 - the smallest downside is the runtime overhead of repeatedly
   reading the file and parse it.

 - as we read it multiple times, it may change anytime. Most
   code in NetworkManager does not expect or handle a change of
   the machine-id.
   Generally, the admin should make sure that the machine-id is properly
   initialized before NetworkManager starts, and not change it. As such,
   a change of the machine-id should never happen in practice.
   But if it would change, we would get odd behaviors. Note for example
   how generate_duid_from_machine_id() already cached the generated DUID
   and only read it once.
   It's better to pick the machine-id once, and rely to use the same
   one for the remainder of the program.
   If the admin wants to change the machine-id, NetworkManager must be
   restarted as well (in case the admin cares).
   Also, as we now only load it once, it makes sense to log an error
   (once) when we fail to read the machine-id.

 - previously, loading the machine-id could fail each time. And we
   have to somehow handle that error. It seems, the best thing what we
   anyway can do, is to log an error once and continue with a fake
   machine-id. Here we add a fake machine-id based on the secret-key
   or the boot-id. Now obtaining a machine-id can no longer fail
   and error handling is no longer necessary.

Also, ensure that a machine-id of all zeros is not valid.

Technically, a machine-id is not an RFC 4122 UUID. But it's
the same size, so we also use NMUuid data structure for it.

While at it, also refactor caching of the boot-id and the secret
key. In particular, fix the thread-safety of the double-checked
locking implementations.
2018-11-13 19:04:34 +01:00
Thomas Haller
e1413111a7 core: minor cleanup of initializing nm_utils_get_testing()
- add a commnt about thread-safety.

- minor refactoring initializing the value in nm_utils_get_testing().
  Instead of returning the flags we just set, go back to the begin
  and re-read the value (which must be initialized by now). No big
  difference, but feels a bit nicer to me.
2018-11-13 19:04:34 +01:00
Thomas Haller
eb9f950a33 all: cleanup GChecksum handling
- prefer nm_auto_free_checksum over explicit free.
- use nm_utils_checksum_get_digest*().
- prefer defines for digest length.
- assume g_checksum_new() cannot fail.
2018-11-13 18:30:03 +01:00