Commit Graph
2157 Commits
Author SHA1 Message Date
Yu Watanabe f51e7eeb7c fuzz: modernize fuzz-dhcp-server
- Do not include .c file.
- Use ASSERT_OK() and friends.
2026-05-13 00:47:03 +09:00
Yu Watanabe e507487b6d dhcp-protocol: introduce more sub-options for DHCP Relay Agent Information option
These new values will be used later.
2026-05-13 00:46:09 +09:00
Yu Watanabe 25482d832c sd-dhcp-lease: drop sd_dhcp_lease.have_subnet_mask and have_broadcast
NULL address is invalid in both cases. Let's refuse to use them when NULL.
2026-05-13 00:43:00 +09:00
Yu Watanabe 28423ea18c dhcp-message: introduce dhcp_message_{append,get}_option_hostname() and related functions
These are for DHCP options 12 (Hostname) and 81 (FQDN) options.
2026-05-13 00:27:49 +09:00
Yu Watanabe aa9584a037 dhcp-message: introduce dhcp_message_{append,get}_option_parameter_request_list()
These are for DHCP option 55 (parameter request list).
2026-05-13 00:27:49 +09:00
Yu Watanabe a6a6e371f7 dhcp-message: introduce dhcp_message_{append,get}_option_client_id()
These are for DHCP option 61 (client ID).
2026-05-13 00:27:49 +09:00
Yu Watanabe 1c4ee9e969 dhcp-message: introduce dhcp_message_{append,get}_option_string()
These are for DHCP options that takes a string e.g. DHCP options
17 (root path), 60 (vendor class identifier), and so on.
2026-05-13 00:27:49 +09:00
Yu Watanabe 174a61135c dhcp-message: introduce dhcp_message_{append,get}_option_addresses()
These functions support multiple addresses.

These are for e.g. DHCP options 6 (DNS servers), 42 (NTP servers) and so on.
2026-05-13 00:27:49 +09:00
Yu Watanabe 4b2ff0a00f dhcp-message: introduce dhcp_message_{append,get}_option_address()
These are equivalent to dhcp_message_{append,get}_option_be32(), but for
type safety.

These are for e.g. DHCP options 50 (requested IP address).
2026-05-13 00:27:49 +09:00
Yu Watanabe 7b97d772a2 dhcp-message: introduce dhcp_message_{append,get}_option_sec()
These are for e.g. DHCP options 51 (lease time), 58 (renewal time), and
59 (rebinding time).
2026-05-13 00:27:49 +09:00
Yu Watanabe 8c18bb6547 dhcp-message: introduce sd_dhcp_message object and several functions for the object 2026-05-13 00:27:49 +09:00
Yu Watanabe 30b14a0886 dhcp: use struct iovec_wrapper to manage user class 2026-05-12 20:06:28 +09:00
Yu Watanabe fa881fda15 sd-dhcp-option: drop unused sd_dhcp_option 2026-05-12 20:06:28 +09:00
Yu Watanabe 431ec1b145 dhcp: use TLV object to manage extra and vendor options
Note, previously we replaced the previous option with the same option code with
new one. But, DHCP message can have multiple options with same option code.
Hence, this make the conf parser not replace, but append new one.
2026-05-12 20:06:28 +09:00
Yu Watanabe 47747cd212 sd-dhcp-protocol: rename DHCP option 43, 124, and 125
There are four DHCP options with confusing names:
Option 43: Vendor-Specific Information
Option 60: Vendor Class Identifier
Option 124: Vendor-Identifying Vendor Class
Option 125: Vendor-Identifying Vendor-Specific Information

Let's use their full names for their corresponding enums.
2026-05-12 20:06:28 +09:00
Yu Watanabe 320ae462b1 tlv-util: introduce tlv-util that handles Tag-Length-Value data format
In many network protocols e.g. DHCP, the TLV format is used.
Let's introduce a simple parser and builder of the data format.
2026-05-12 15:53:12 +09:00
Zbigniew Jędrzejewski-Szmek f3ee3510a3 sd-dhcp-client: avoid taking and dropping a reference
The helper would create a new ref, even though we had one handy
and didn't need to create a new ref. So change the helper to
take an existing reference.
2026-05-08 11:14:32 +02:00
Zbigniew Jędrzejewski-Szmek 62a489fbf9 tree-wide: rename unref_and_replace_full to unref_and_replace_new_ref
We have a number of *_unref_and_replace macros. One could think that
they are like the various free_and_replace variants, but they actually
create a new ref to the passed object. The free_and_replace variants
take ownership of the argument. This inconsistency is surprising. Rename
all those functions to have "_new_ref" at the end to make the difference
clear.
2026-05-08 11:14:13 +02:00
Lennart Poettering 99ce7a0770 options: get rid of "on_error" parameter to FOREACH_OPTION
I am really not a fan of full code lines passed to macros as parameters.
Let's get rid of the 3rd parameter of FOREACH_OPTION() hence:

1. Let's return errors just as a regular value (though a negative one),
   that can be handled via a OPTION_ERROR case statement for the switch.
   This normalizes handling of the error, just like any other event
   returned by the option parser.

2. In order to avoid exploding the amount of boilerplate in each use
   (that just propagates the error on OPTION_ERROR), let's then
   introduce an explicit FOREACH_OPTION_OR_RETURN(), that returns from
   the calling function on its own (and makes that clear in the name).

Together this cleans up, normalizes the logic and shortens the code.
2026-04-30 11:12:33 +01:00
Zbigniew Jędrzejewski-Szmek 5ff0ccaf8b tree-wide: change option_parse() to return option and arg via internal state
It was requested to make the 'c', 'opt', and 'arg' params the same, i.e.
defined through the FOREACH_OPTION macro. But we can't do that easily,
because 'c' was defined in the for loop definition, and we can only
define variables of the same type in that way. Also, in some cases we
need only 'c', in other cases with need 'c' and 'arg, in some cases 'c'
and 'opt', and in other cases all three. We'd need to either
conditionalize or mark those variables with _unused_ to deal with
compiler warnings. But a different approach works quite nicely: add
state.opt and state.arg to show the current option and it's argument.
(The short names are picked on purpose to reduce verbosity since those
are used a lot.)
2026-04-27 11:33:10 +02:00
Yu Watanabe 3b4e01637f ip-util: define IPV4_MIN_REASSEMBLY_SIZE
The number will be later used at several places.
2026-04-25 07:26:02 +09:00
Yu Watanabe 11def23206 ip-util: introduce udp_packet_verify()
This is mostly equivalent to dhcp_packet_verify_headers(), but
- it optionally returns the UDP payload as iovec, and
- supports IP header with options,
- check packet length more strictly.
2026-04-25 07:25:18 +09:00
Yu Watanabe e8497d6825 ip-util: introduce udp_packet_build()
Then make dhcp_packet_append_ip_headers() just a wrapper of the new
function. Currently, the wrapper is inefficient, but will be removed in
a later commit.
2026-04-25 07:22:28 +09:00
Yu Watanabe 7c87767d14 ip-util: introduce ip_checksum()
It is equivalent to dhcp_packet_checksum(). It is generic
and not specific to DHCP. Hence, renamed to ip_checksum().
2026-04-25 05:23:37 +09:00
Yu Watanabe e06115cb8b sd-dhcp-client: add FIXME comment about the state callback
At least currently, it is a theoretical concern, as networkd does not
change the client state in the callback.
2026-04-24 07:40:08 +09:00
Yu Watanabe 6ee065ed99 sd-dhcp-client: rework discover/request_attempts counter
discover_attempts should be reset only when
- the client is stopped, to make the counter starts from zero on
  the next invocation.
- we acquire a bound lease, to make the counter starts from zero
  when the lease is expired.

request_attempts should be reset only when the client enter a new state
that sends DHCPREQUEST, that is, when enter one of the REBOOTING,
REQUESTING, RENEWING, and REBINDING state.

This moves resetting counter to client_set_state() as it should happen
only when the state transition.
2026-04-24 07:40:08 +09:00
Yu Watanabe 2dff63a31c sd-dhcp-client: notify SD_DHCP_CLIENT_EVENT_EXPIRED only when we already have a bound lease
Otherwise, if we emit the notification without a valid bound lease, networkd
may be confused (of course should not, but for safety).

Also, increment the delay before calling client_start_delayed().
Otherwise, the first reboot is done instantaneously.
2026-04-24 07:40:08 +09:00
Yu Watanabe b831cd00e6 sd-dhcp-client: propagate failure in setting timer and stop the client
If we fail to setup timer event sources about the lease lifetime or
T1/T2, then the lease will be never updated, and the user (networkd)
will not receive any notification about the expire. The situation is
terrible. Let's stop the client with error code earlier, and notify the
failure to networkd.
2026-04-24 07:40:08 +09:00
Yu Watanabe bb5b2f9e5a sd-dhcp-client: simplify the implementation of IPv6 Only mode support
This drop delay after ACK, as it has many problems. See comment in
sd_dhcp_client_is_waiting_for_ipv6_connectivity() for more details.
This way, the logic becomes much much simpler.

Also, do not restart the client if we lost IPv6 connectivity in
sd_dhcp_client side, but restart the client by networkd. As,
sd_dhcp_client does not know if we can start the client or not,
e.g., the interface may be currently down.
2026-04-24 07:40:08 +09:00
Yu Watanabe f0b9b679ff sd-dhcp-client: simply enter renewing/rebinding state send DHCPREQUEST on T1/T2
It is not necessary to enable another timer event source to send
DHCPREQUEST from the T1/T2 timer event source. Just call the callback
function for sending message.

Also, T1 hits only we have a bound lease. Drop spurious conditions.
2026-04-24 07:40:07 +09:00
Yu Watanabe ffc3d5f812 sd-dhcp-client: initialize event source and so on in client_start_delayed()
When we start the client, any previous state/configuration should be cleaned.
Let's effectively do the same thing as client_initialize() in that
function.

This also several assertions in client_start_delayed() to
sd_dhcp_client_start(). These kind of checks should be done earlier.
2026-04-24 07:40:07 +09:00
Yu Watanabe 0b3cbfd1bc sd-dhcp-client: enter the SELECTING state before sending DHCPDISCOVER
Similarly, enter the REBOOTING state before sending DHCPREQUEST on reboot.

Also, this makes DHCPREQUEST message is sent several times also in REBOOTING
state. Previously, we wait about 4 seconds after DHCPREQUEST on reboot, and
entered the init state if no response. Now we wait 1 second after the first
DHCPREQUEST, resend another DHCPREQUEST, wait 2 seconds, then enter the
init state if no response. So, even in the worst case, we have slight
speed up.
2026-04-24 07:40:07 +09:00
Yu Watanabe ffafefbcce sd-dhcp-client: replace max_request_attempts with constant macro 2026-04-24 07:40:07 +09:00
Yu Watanabe c32105081f sd-dhcp-client: introduce client_send_discover()
No functional change, just refactoring.
2026-04-24 07:40:07 +09:00
Yu Watanabe 16d08897bb sd-dhcp-client: open socket when necessary and close it when unnecessary
To make gracefully ignore unexpected messages from outside at unexpected timing.
This potentially reduces work load to handle such messages, and slightly
reduces attack surface by malicious DHCP messages.

This also makes the socket fd is owned by the relevant IO event source.

Except for the performance optimization and security hardening, this
should not change any behaviors. So, just refactoring.
2026-04-24 07:40:07 +09:00
Yu Watanabe 3817ab9e14 sd-dhcp-client: add one missing assertion
Found and suggested by Claude. Nice!
2026-04-24 07:40:07 +09:00
Yu Watanabe 6a3b0e8475 sd-dhcp-client: move the object definition to the header
Then, we can split the long sd-dhcp-client.c into small pieces later.

This also drops redundant typedef, which is also in sd-dhcp-client.h.
2026-04-24 07:40:07 +09:00
Yu Watanabe 7aa8eabc8e dhcp-protocol: introduce several constants, string table lookups, and so on (#41710) 2026-04-24 03:54:55 +09:00
Zbigniew Jędrzejewski-Szmek 53ea569d8a test-ndisc-send: convert to the new option parser
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-22 14:19:01 +02:00
Lennart Poettering 812aa57d2c string-util: beef up string_is_safe()
This tightens the checks of string_is_safe() and then adds flags to
relax certain aspects of it.

This does alter the rules on certain strings we pass a bit. We mostly
tighten the rules (but I think it's find and good) but we relax them on
others.

I let claude review the changes in behaviour for the various call sites
that I made. It summarized things in this table:

  ╭───────────────────────────────────────────────────┬──────────────────────────────────────────────╮
  │ CALL SITE                                         │ EFFECTIVE DELTA                              │
  ├───────────────────────────────────────────────────┼──────────────────────────────────────────────┤
  │ src/basic/syslog-util  log_namespace_name_valid   │ +UTF-8 required (globs already blocked)      │
  │ src/bootctl  --efi-boot-option-description        │ RELAXED: '\' and quotes now permitted        │
  │ src/core/dbus-manager  pretimeout governor        │ +UTF-8, +no-globs                            │
  │ src/core/load-fragment  ExecStart= path           │ +UTF-8, +no-globs                            │
  │ src/core/main  pretimeout governor (kcmdline)     │ +UTF-8, +no-globs                            │
  │ src/core/service  sd_notify STATUS=               │ +no-globs (ASCII-only preserved)             │
  │ src/home/homectl  --<identity field>=             │ empty now REJECTED; +UTF-8                   │
  │ src/libsystemd-network  dhcp_option_parse_string  │ (equivalent, just explicit)                  │
  │ src/libsystemd-network  sd_dhcp_server boot_fname │ ""→NULL coerced; else equivalent             │
  │ src/libsystemd/journal  SYSLOG_IDENTIFIER fb      │ +UTF-8, +no-globs                            │
  │ src/libsystemd/sd-json  SD_JSON_STRICT strings    │ +UTF-8 required                              │
  │ src/login/logind  session desktop=                │ +UTF-8 required                              │
  │ src/pcrlock  EFI variable string                  │ +UTF-8                                       │
  │ src/pcrlock  EFI action string                    │ RELAXED: empty + '\' now ok; +UTF-8          │
  │ src/resolve  dns-delegate id (from filename)      │ +UTF-8, +no-globs                            │
  │ src/shared/boot-entry  boot_entry_token_valid     │ (equivalent)                                 │
  │ src/shared/conf-parser  section header            │ +UTF-8, +no-globs                            │
  │ src/shared/conf-parser  CONFIG_PARSE_STRING_SAFE  │ +UTF-8 required                              │
  │ src/shared/kbd-util  keymap_is_valid              │ (equivalent; folded into STRING_FILENAME)    │
  │ src/shared/tpm2  nvpcr name                       │ +UTF-8 required                              │
  │ src/shared/vconsole  x11 layout/model/variant/opt │ +UTF-8, +no-globs                            │
  │ src/systemctl  --kernel-cmdline=                  │ +0x7f DEL rejected; empty path split out     │
  │ src/veritysetup  salt=                            │ RELAXED: safety check removed entirely       │
  │ src/vmspawn  --ssh-key-type=                      │ +UTF-8 required                              │
  ╰───────────────────────────────────────────────────┴──────────────────────────────────────────────╯
2026-04-21 17:07:53 +02:00
Yu Watanabe 06188d2663 dhcp-protocol: introduce dhcp_option_code_to_string() 2026-04-19 08:31:07 +09:00
Yu Watanabe 5c907b2b2b dhcp-protocol: introduce {bootp,dhcp}_message_type_to_string() 2026-04-19 08:31:07 +09:00
Yu Watanabe 6fd89f305a dhcp-protocol: rename several dhcp message types
These are unused, hence we can freely rename them.
2026-04-19 08:31:07 +09:00
Yu Watanabe 19a4b5184e dhcp-protocol: define BOOTP_MESSAGE_SIZE
It will be used later.
2026-04-19 08:31:07 +09:00
Yu Watanabe 68553bb03a dhcp-protocol: introduce DHCPMessageHeader struct
It is similar to DHCPMessage, but does not have the tail 'options'
variable array. Then, we can use it in another struct.
2026-04-19 08:31:07 +09:00
Yu Watanabe c651876cc9 dhcp-protocol: Option Overload (52) DHCP option value takes flags 2026-04-19 08:31:07 +09:00
Yu Watanabe 366e1d264a sd-dhcp-client: fix memleak of sd_dhcp_client.timeout_ipv6_only_mode
This also drops unnecessary zero assignments.
2026-04-19 03:25:27 +09:00
Yu Watanabe 8bb669712e string-util: make make_cstring() take void* rather than char*
It is typically used for making C string embedded in a binary data.
Hence, the input pointer may not be char*.
2026-04-17 19:24:53 +02:00
Zbigniew Jędrzejewski-Szmek b8514cff52 libsystemd-network: use DEFINE_POINTER_ARRAY_FREE_FUNC, rename cleanup function 2026-04-10 15:08:02 +02:00
Zbigniew Jędrzejewski-Szmek 954243f2bc libsystemd-network: use DEFINE_ARRAY_FREE_FUNC, rename cleanup func 2026-04-10 15:08:02 +02:00