Commit graph

167 commits

Author SHA1 Message Date
Thomas Haller
ff694f42a7
dhcp/systemd: pass client instance to lease_to_ip6_config()
This makes it more consistent with nettools' lease_to_ip4_config().
The benefit of having a self pointer, is that it provides the necessary
context for logging. Without it, these functions cannot correctly log.

At this point, it's clearer to get the necessary data directly from the
DHCP client instance, instead of having the caller passing them on
(redundantly).
2022-06-27 10:53:40 +02:00
Thomas Haller
c7c57e8fb9
dhcp/nettools: log message about guessing subnet mask for IPv4 2022-06-27 10:53:40 +02:00
Thomas Haller
f0d132bda9
dhcp: add nm_dhcp_client_create_l3cd() helper 2022-06-27 10:53:39 +02:00
Thomas Haller
c06e6390a4
dhcp/nettools: normalize subnet netmask in nettools client
For an IPv4 subnet mask we expect that all the leading bits are set (no
"holes"). But _nm_utils_ip4_netmask_to_prefix() does not enforce that,
and tries to make the best of it.

In face of a netmask with holes, normalize the mask.
2022-06-27 10:53:39 +02:00
Thomas Haller
57dfa999f7
dhcp/nettools: accept missing "subnet mask" (option 1) in DHCP lease
Do the same as dhclient plugin in nm_dhcp_utils_ip4_config_from_options().

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1037
2022-06-27 10:53:36 +02:00
Thomas Haller
863b71a8fe
all: use internal _nm_utils_ip4_netmask_to_prefix()
We have two variants of the function: nm_utils_ip4_netmask_to_prefix()
and _nm_utils_ip4_netmask_to_prefix(). The former only exists because it
is public API in libnm. Internally, only use the latter.
2022-06-27 10:50:24 +02:00
Beniamino Galvani
2807f6a893 dhcp: nettools: save the lease after it gets accepted
Currently the lease gets saved only on the extended (renewal)
event. Also save it after it gets accepted.

Fixes: 52a0fe584c ('dhcp/nettools: better track currently granted lease')

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1261
2022-06-17 18:11:30 +02:00
Beniamino Galvani
393bc628ff dhcp: wait DAD completion for DHCPv6 addresses
Wait that addresses received through DHCPv6 complete duplicate address
detection before reporting that the lease can be used.

Fixes: 58287cbcc0 ('core: rework IP configuration in NetworkManager using layer 3 configuration')

https://bugzilla.redhat.com/show_bug.cgi?id=2096386
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1258
2022-06-16 16:26:14 +02:00
Thomas Haller
240ec7f891
dhcp: implement ACD (address collision detection) for DHCPv4
This was working for internal plugin in the past, but broken by l3cfg
rework with 1.36. Re-add it. Not it also works with dhclient. For other
plugins, it's not really working, because we can't decline.

Now NMDhcpClient does ACD (using NML3Cfg) and abstracts that from
the caller (NMDevice).

It is complicated. Because there is state involved, meaning, we need
to remember the current state for ACD and react on and handle a
multitude of events. Getting this right, is non-trivial.

What we want is that if ACD fails, we decline the lease (and don't use
it).

https://bugzilla.redhat.com/show_bug.cgi?id=1713380
2022-06-01 10:37:44 +02:00
Thomas Haller
156d84217c
dhcp/dhclient: implement accept/decline (ACD) for dhclient plugin
dhclient itself doesn't do ACD. However, it expects the dhclient-script
to exit with non-zero status, which causes dhclient to send a DECLINE.

`man dhclient-script`:

  BOUND:
     Before actually configuring the address, dhclient-script should
     somehow ARP for it and exit with a nonzero status if it receives a
     reply. In this case, the client will send a DHCPDECLINE  message  to
     the server and acquire a different address.   This may also be done in
     the RENEW, REBIND, or REBOOT states, but is not required, and indeed may
     not be desirable.

See also Fedora's dhclient-script ([1]).

https://gitlab.isc.org/isc-projects/dhcp/-/issues/67#note_97226
33226f2d76/client/dhclient.c (L1652)

[1] a8f6fd046f/f/dhclient-script (_878)

https://bugzilla.redhat.com/show_bug.cgi?id=1713380
2022-05-31 18:32:36 +02:00
Thomas Haller
0f6df633fa
dhcp: minor cleanup of accept/decline functions in "nm-dhcp-client.c"
- assign the result of NM_DHCP_CLIENT_GET_CLASS() to a local variable.
  It feels nicer to only call the macro once. Of course, the macro
  expands to plain pointer dereferences, so there is little difference
  in terms of executed code.

- handle the default case with no virtual function first.
2022-05-31 18:32:36 +02:00
Thomas Haller
4f13383460
dhcp/nettools: pop n-dhcp4 events after select/accept/decline to process logging events 2022-05-31 18:32:36 +02:00
Thomas Haller
8f8839dd2a
dhcp/nettools: add helper function dhcp4_event_pop_all_events()
Will be used next.
2022-05-31 18:32:35 +02:00
Thomas Haller
85b15e02fd
dhcp/nettools: cleanup logging for dhcp4_event_handle()
It's pretty pointless to log

  <trace> [1653389116.6288] dhcp4 (br0): client event 7
  <debug> [1653389116.6288] dhcp4 (br0): received OFFER of 192.168.121.110 from 192.168.121.1

where the obscure event #7 is only telling you that we are going
to log something.  Handle logging events first.

In general, drop the "client event %d" message and make sure that all
code paths log something (useful), so we can see in the log that the
event was reached.
2022-05-31 18:32:35 +02:00
Thomas Haller
52a0fe584c
dhcp/nettools: better track currently granted lease
When we accept/decline a lease, then that only works if we are in state
GRANTED. n-dhcp4 API also requires us, to provide the exact lease, that
we were announced earlier.

As such, we need to make sure that we don't accept/decline in the wrong
state. That means, to keep track of what we are doing more carefully.

The functions _dhcp_client_accept()/_dhcp_client_decline() now take
a l3cd argument, the one that we announced earlier. And we check that it
still matches.
2022-05-31 18:32:35 +02:00
Thomas Haller
4a256092ee
dhcp: move accept/decline function inside "nm-dhcp-client.c"
They are no longer used from outside, NMDhcpClient fully handles this.
Make them static and internal.

Also, decline is currently unused. It will be used soon, with ACD
support.
2022-05-31 18:32:35 +02:00
Thomas Haller
31c52545ed
dhcp: add and use _NMLOG() macro for "nm-dhcp-manager.c" 2022-05-31 18:32:35 +02:00
Thomas Haller
1760cea47c
dhcp: improve warning logging for dhcp4_event_handle() failure 2022-05-31 18:32:34 +02:00
Thomas Haller
479562815c
dhcp: ensure a valid DHCPv4 lease has an address for dhclient
The same check is also for nettools' n-dhcp4 client. It's useful to
being able to rely on certain things, like that an DHCPv4 lease always
has exactly one address (not equal to 0.0.0.0).
2022-05-31 18:32:34 +02:00
Thomas Haller
9abcf3a53c
dhcp/trivial: rename connect_l3cfg_notify() to l3_cfg_notify_check_connected()
The function subscribes a callback l3_cfg_notify_cb(). Rename so that
related functions have a clearly related name.
2022-05-31 18:32:34 +02:00
Thomas Haller
7db07faa5e
dhcp: replace switch in l3_cfg_notify_cb() with if blocks
The l3_cfg_notify_cb() handler is used for different purposes, and
different events will be considered.

Usually a switch statement is very nice for enums, especially if all
enum values should be handled (because the compiler can warn about
unhandled cases). In this case, not all events are supposed to be
handled. At this point, it seems nicer to just use an if block. It
better composes.

The compiler should be able to optimize both variants to the same
result. In any case, checking some integers for equality is in any case
going to be efficient.
2022-05-31 18:32:34 +02:00
Thomas Haller
e756533002
dhcp: move addr-family specific data to union in NMDhcpClientPrivate 2022-05-31 18:32:34 +02:00
Thomas Haller
05cc160494
dhcp/trivial: drop obsolete code comment
This is done already.
2022-05-31 18:32:34 +02:00
Thomas Haller
cd09f3d364
dhcp: fix logging of event in _nm_dhcp_client_notify() 2022-05-31 18:32:34 +02:00
Thomas Haller
7f943f5fa6
dhcp: merge nm_dhcp_client_start_ip4() and nm_dhcp_client_start_ip6() implementations
As almost always, there is a point in keeping IPv4 and IPv6 implementations
similar. Behave different where there is an actual difference, at the bottom
of the stack.
2022-05-16 16:37:45 +02:00
Thomas Haller
2b8aeba06d
dhcp: move code in "nm-dhcp-client.c" (2) 2022-05-16 16:37:44 +02:00
Thomas Haller
ea13cff76c
dhcp: assert that resources are freed in NMDhcpClient.dispose() 2022-05-16 16:37:44 +02:00
Thomas Haller
600467b96f
dhcp: minor cleanup in config_init() 2022-05-16 16:37:43 +02:00
Thomas Haller
f0ec297739
dhcp: use packed strv array for NMDhcpClientConfig.reject_servers
No need to do it otherwise.
2022-05-16 16:37:43 +02:00
Thomas Haller
892cde1436
dhcp: remove assertion in nm_dhcp_client_handle_event()
Technically, g_warn_if_reached() may not be an assertion, according to
glib. However, there is G_DEBUG=fatal-warnings and we want to run with
that.

So this is an assertion to us. Also, logging to stderr/stdout is not a
useful thing to the daemon. Don't do this. Especially, since it depends
on user provided (untrusted) input.
2022-05-16 16:37:42 +02:00
Thomas Haller
9097679aad
dhcp: move code in nm_dhcp_client_handle_event() 2022-05-16 16:37:42 +02:00
Thomas Haller
802f343d9f
dhcp: drop NMDhcpState enum
It's unused now.
2022-05-16 16:37:41 +02:00
Thomas Haller
97e65e4b50
dhcp: rename/refactor nm_dhcp_client_set_state() to be notifications
Optimally we want stateless, pure code. Obviously, NMDhcpClient needs to
keep state to know what it's doing. However, we should well encapsulate
the state inside NMDhcpClient, and only accept events/notifications that
mutate the internal state according to certain rules.

Having a function public set_state(self, new_state) means that other
components (subclasses of NMDhcpClient) can directly mangle the state.
That means, you no longer need to only reason about the internal state
of NMDhcpClient (and the events/notifications/state-changes that it
implements). You also need to reason that other components take part of
maintaining that internal state.

Rename nm_dhcp_client_set_state() to nm_dhcp_client_notify(). Also, add
a new enum NMDhcpClientEventType with notification/event types.

In practice, this is only renaming. But naming is important, because it
suggests the reader how to think about the code.
2022-05-16 16:37:41 +02:00
Thomas Haller
9761e38f7e
dhcp: fix handling of NM_DHCP_STATE_NOOP
The "noop" state is almost unused, however, nm_dhcp_set_state()
has a check "if (new_state >= NM_DHCP_STATE_TIMEOUT)", so the order
of the NOOP state matters.

Fix that by reordering.

Also, just return right away from NOOP.
2022-05-16 16:37:41 +02:00
Thomas Haller
f102051a29
dhcp: drop most of NMDhcpState usage from nm_dhcp_client_handle_event()
NMDhcpState is very tied to events from dhclient. But most of these
states we don't care about, and NMDhcpClient definitely should abstract
and hide them.

We should repurpose NMDhcpState to simpler state. For that, first drop
the state from nm_dhcp_client_handle_event().

This is only the first step (which arguably makes the code more
complicated, because reason_to_state() gets spread out and the logic
happens more than once). That will be addressed next.
2022-05-16 16:37:40 +02:00
Thomas Haller
70cbf3dc1e
dhcp/trivial: add comment about nm_dhcp_utils_merge_new_dhcp6_lease() 2022-05-16 16:37:40 +02:00
Thomas Haller
8d121b17b5
dhcp: move code in "nm-dhcp-client.c"
So that it makes more sense, related parts are closer together.
2022-05-16 16:34:32 +02:00
Thomas Haller
1093e66776
dhcp: minor code cleanups in "nm-dhcp-client.c" 2022-05-16 16:34:32 +02:00
Thomas Haller
c8542a5d50
dhcp: use GSource for watching child process instead of numeric source id 2022-05-16 16:34:31 +02:00
Thomas Haller
98f7081db2
dhcp: minor cleanup in maybe_add_option()
- return early to avoid nested block.
- use NM_STR_HAS_PREFIX() over g_str_has_prefix(), because that
  can be inlined and only accepts a C literal as prefix argument.
2022-05-16 16:34:31 +02:00
Thomas Haller
cb2ab420a2
dhcp: don't assert against untrusted data in maybe_add_option() 2022-05-16 16:34:31 +02:00
Thomas Haller
668d8050a5
dhcp: cleanup bytearray_variant_to_string()
- the code comment was unclear/wrong. If something comes from an environment
  variables it is *NOT* UTF-8 safe. Also, we convert all non-ASCII characters,
  not only non UTF-8 characters.

- as we already convert the string to ASCII, the check whether it's UTF-8
  is bogus.

- using GString is unnecessary.
2022-05-16 16:34:31 +02:00
Thomas Haller
9b9c07530c
dhcp: cleanup reason_to_state() in "nm-dhcp-client.c"
- use NM_IN_STRSET_ASCII_CASE().
- don't use else block after we return.
- don't accept the "iface" argument just for logging. The caller
  can do the logging, if they wish.
2022-05-16 16:32:22 +02:00
Beniamino Galvani
7a3774f62d dhcp: log messages about invalid DHCP options
Log messages when invalid DHCP options are found. For example:

  <info> dhcp4 (eth0): error parsing DHCP option 6 (domain_name_servers): address 0.0.0.0 is ignored
  <info> dhcp4 (eth0): error parsing DHCP option 12 (host_name): '.example.com' is not a valid DNS domain
  <info> dhcp4 (eth0): error parsing DHCP option 26 (interface_mtu): value 60 is smaller than 68

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1225
2022-05-16 09:49:06 +02:00
Thomas Haller
2875ad7e50
dhcp: fix ignoring addresses with DHCPv6 otherconf (O flag)
With O flag (otherconf mode), don't add the IPv6 addresses to the
collected lease.

An alternative would be to add it initially, but ignore it when
merging the configuration in NML3Cfg. The idea of that would be that if
the mode switches from otherconf to managed, that we already have the
address. However, depending on the mode we made a different DHCPv6
request. That means, if the mode changes we anyway cannot just use the
previous lease, because it might not contain all the information. So
it seems better to ignore the address early.

Fixes: 58287cbcc0 ('core: rework IP configuration in NetworkManager using layer 3 configuration')

https://bugzilla.redhat.com/show_bug.cgi?id=2083968
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/953

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1220
2022-05-11 19:06:00 +02:00
Thomas Haller
41df480fdd
dhcp: fix setting "-S" flag for dhclient info-only requests
Fixes: 58287cbcc0 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
2022-05-11 19:03:46 +02:00
Thomas Haller
bacd3e1482
dhcp: always explicitly set request/information-request flags for internal DHCPv6 client
It seems clearer to explicitly set this always, and not rely on the
defaults.
2022-05-11 19:03:45 +02:00
Beniamino Galvani
15a4211303 dhcp: fix logging domain
Fix wrong domain when logging a lease:

  dhcp6 (veth0):   valid_lft 7200
  dhcp6 (veth0):   preferred_lft 5400
  dhcp6 (veth0):   address fd00:db8:db8::11:2233:4455
  dhcp (veth0):   domain search 'domain'
2022-05-03 09:07:29 +02:00
Beniamino Galvani
f20ac6bdc7 dhcp: improve logging for DHCPv6 merged leases
Instead of logging the event-id, which is composed from options that
are already visible in the log, it's more interesting to log that the
lease was merged.
2022-05-03 09:07:29 +02:00
Thomas Haller
c4f5111920
all: use nm_hostname_is_valid() instead of systemd code 2022-04-20 12:07:04 +02:00