Skip to content

Commit ec00453

Browse files
authored
Merge pull request systemd#22412 from yuwata/sd-dhcp6-client-cleanups
sd-dhcp6-client: several fixes and cleanups
2 parents b6fc524 + 119c00c commit ec00453

22 files changed

+2175
-2263
lines changed

src/basic/ordered-set.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ int _ordered_set_ensure_allocated(OrderedSet **s, const struct hash_ops *ops HA
1818
int _ordered_set_ensure_put(OrderedSet **s, const struct hash_ops *ops, void *p HASHMAP_DEBUG_PARAMS);
1919
#define ordered_set_ensure_put(s, hash_ops, key) _ordered_set_ensure_put(s, hash_ops, key HASHMAP_DEBUG_SRC_ARGS)
2020

21+
static inline void ordered_set_clear(OrderedSet *s) {
22+
return ordered_hashmap_clear((OrderedHashmap*) s);
23+
}
24+
25+
static inline void ordered_set_clear_free(OrderedSet *s) {
26+
return ordered_hashmap_clear_free((OrderedHashmap*) s);
27+
}
28+
2129
static inline OrderedSet* ordered_set_free(OrderedSet *s) {
2230
return (OrderedSet*) ordered_hashmap_free((OrderedHashmap*) s);
2331
}

src/libsystemd-network/dhcp-identifier.c

Lines changed: 87 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,27 @@
88
#include "sd-id128.h"
99

1010
#include "dhcp-identifier.h"
11-
#include "dhcp6-protocol.h"
1211
#include "netif-util.h"
1312
#include "siphash24.h"
1413
#include "sparse-endian.h"
1514
#include "stat-util.h"
16-
#include "stdio-util.h"
15+
#include "string-table.h"
1716
#include "udev-util.h"
18-
#include "virt.h"
1917

2018
#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
2119
#define APPLICATION_ID SD_ID128_MAKE(a5,0a,d1,12,bf,60,45,77,a2,fb,74,1a,b1,95,5b,03)
2220
#define USEC_2000 ((usec_t) 946684800000000) /* 2000-01-01 00:00:00 UTC */
2321

24-
int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len, bool strict) {
22+
static const char * const duid_type_table[_DUID_TYPE_MAX] = {
23+
[DUID_TYPE_LLT] = "DUID-LLT",
24+
[DUID_TYPE_EN] = "DUID-EN/Vendor",
25+
[DUID_TYPE_LL] = "DUID-LL",
26+
[DUID_TYPE_UUID] = "UUID",
27+
};
28+
29+
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(duid_type, DUIDType);
30+
31+
int dhcp_validate_duid_len(DUIDType duid_type, size_t duid_len, bool strict) {
2532
struct duid d;
2633

2734
assert_cc(sizeof(d.raw) >= MAX_DUID_LEN);
@@ -57,110 +64,146 @@ int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len, bool strict) {
5764
return 0;
5865
}
5966

60-
int dhcp_identifier_set_duid_llt(struct duid *duid, usec_t t, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len) {
67+
static int dhcp_identifier_set_duid_llt(const uint8_t *addr, size_t addr_len, uint16_t arp_type, usec_t t, struct duid *ret_duid, size_t *ret_len) {
6168
uint16_t time_from_2000y;
6269

63-
assert(duid);
64-
assert(len);
6570
assert(addr);
71+
assert(ret_duid);
72+
assert(ret_len);
73+
74+
if (addr_len == 0)
75+
return -EOPNOTSUPP;
6676

6777
if (arp_type == ARPHRD_ETHER)
6878
assert_return(addr_len == ETH_ALEN, -EINVAL);
6979
else if (arp_type == ARPHRD_INFINIBAND)
7080
assert_return(addr_len == INFINIBAND_ALEN, -EINVAL);
7181
else
72-
return -EINVAL;
82+
return -EOPNOTSUPP;
7383

7484
if (t < USEC_2000)
7585
time_from_2000y = 0;
7686
else
7787
time_from_2000y = (uint16_t) (((t - USEC_2000) / USEC_PER_SEC) & 0xffffffff);
7888

79-
unaligned_write_be16(&duid->type, DUID_TYPE_LLT);
80-
unaligned_write_be16(&duid->llt.htype, arp_type);
81-
unaligned_write_be32(&duid->llt.time, time_from_2000y);
82-
memcpy(duid->llt.haddr, addr, addr_len);
89+
unaligned_write_be16(&ret_duid->type, DUID_TYPE_LLT);
90+
unaligned_write_be16(&ret_duid->llt.htype, arp_type);
91+
unaligned_write_be32(&ret_duid->llt.time, time_from_2000y);
92+
memcpy(ret_duid->llt.haddr, addr, addr_len);
8393

84-
*len = sizeof(duid->type) + sizeof(duid->llt.htype) + sizeof(duid->llt.time) + addr_len;
94+
*ret_len = sizeof(ret_duid->type) + sizeof(ret_duid->llt.htype) + sizeof(ret_duid->llt.time) + addr_len;
8595

8696
return 0;
8797
}
8898

89-
int dhcp_identifier_set_duid_ll(struct duid *duid, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len) {
90-
assert(duid);
91-
assert(len);
99+
static int dhcp_identifier_set_duid_ll(const uint8_t *addr, size_t addr_len, uint16_t arp_type, struct duid *ret_duid, size_t *ret_len) {
92100
assert(addr);
101+
assert(ret_duid);
102+
assert(ret_len);
103+
104+
if (addr_len == 0)
105+
return -EOPNOTSUPP;
93106

94107
if (arp_type == ARPHRD_ETHER)
95108
assert_return(addr_len == ETH_ALEN, -EINVAL);
96109
else if (arp_type == ARPHRD_INFINIBAND)
97110
assert_return(addr_len == INFINIBAND_ALEN, -EINVAL);
98111
else
99-
return -EINVAL;
112+
return -EOPNOTSUPP;
100113

101-
unaligned_write_be16(&duid->type, DUID_TYPE_LL);
102-
unaligned_write_be16(&duid->ll.htype, arp_type);
103-
memcpy(duid->ll.haddr, addr, addr_len);
114+
unaligned_write_be16(&ret_duid->type, DUID_TYPE_LL);
115+
unaligned_write_be16(&ret_duid->ll.htype, arp_type);
116+
memcpy(ret_duid->ll.haddr, addr, addr_len);
104117

105-
*len = sizeof(duid->type) + sizeof(duid->ll.htype) + addr_len;
118+
*ret_len = sizeof(ret_duid->type) + sizeof(ret_duid->ll.htype) + addr_len;
106119

107120
return 0;
108121
}
109122

110-
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
123+
int dhcp_identifier_set_duid_en(bool test_mode, struct duid *ret_duid, size_t *ret_len) {
111124
sd_id128_t machine_id;
112125
uint64_t hash;
126+
int r;
113127

114-
assert(duid);
115-
assert(len);
116-
117-
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
118-
int r = sd_id128_get_machine(&machine_id);
119-
if (r < 0)
120-
return r;
121-
#else
122-
machine_id = SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10);
123-
#endif
128+
assert(ret_duid);
129+
assert(ret_len);
124130

125-
unaligned_write_be16(&duid->type, DUID_TYPE_EN);
126-
unaligned_write_be32(&duid->en.pen, SYSTEMD_PEN);
131+
if (!test_mode) {
132+
r = sd_id128_get_machine(&machine_id);
133+
if (r < 0)
134+
return r;
135+
} else
136+
/* For tests, especially for fuzzers, reproducibility is important.
137+
* Hence, use a static and constant machine ID.
138+
* See 9216fddc5a8ac2742e6cfa7660f95c20ca4f2193. */
139+
machine_id = SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10);
127140

128-
*len = sizeof(duid->type) + sizeof(duid->en);
141+
unaligned_write_be16(&ret_duid->type, DUID_TYPE_EN);
142+
unaligned_write_be32(&ret_duid->en.pen, SYSTEMD_PEN);
129143

130144
/* a bit of snake-oil perhaps, but no need to expose the machine-id
131145
* directly; duid->en.id might not be aligned, so we need to copy */
132146
hash = htole64(siphash24(&machine_id, sizeof(machine_id), HASH_KEY.bytes));
133-
memcpy(duid->en.id, &hash, sizeof(duid->en.id));
147+
memcpy(ret_duid->en.id, &hash, sizeof(ret_duid->en.id));
148+
149+
*ret_len = sizeof(ret_duid->type) + sizeof(ret_duid->en);
150+
151+
if (test_mode)
152+
assert_se(memcmp(ret_duid, (const uint8_t[]) { 0x00, 0x02, 0x00, 0x00, 0xab, 0x11, 0x61, 0x77, 0x40, 0xde, 0x13, 0x42, 0xc3, 0xa2 }, *ret_len) == 0);
134153

135154
return 0;
136155
}
137156

138-
int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len) {
157+
static int dhcp_identifier_set_duid_uuid(struct duid *ret_duid, size_t *ret_len) {
139158
sd_id128_t machine_id;
140159
int r;
141160

142-
assert(duid);
143-
assert(len);
161+
assert(ret_duid);
162+
assert(ret_len);
144163

145164
r = sd_id128_get_machine_app_specific(APPLICATION_ID, &machine_id);
146165
if (r < 0)
147166
return r;
148167

149-
unaligned_write_be16(&duid->type, DUID_TYPE_UUID);
150-
memcpy(&duid->raw.data, &machine_id, sizeof(machine_id));
168+
unaligned_write_be16(&ret_duid->type, DUID_TYPE_UUID);
169+
memcpy(ret_duid->raw.data, &machine_id, sizeof(machine_id));
151170

152-
*len = sizeof(duid->type) + sizeof(machine_id);
171+
*ret_len = sizeof(ret_duid->type) + sizeof(machine_id);
153172

154173
return 0;
155174
}
156175

176+
int dhcp_identifier_set_duid(
177+
DUIDType duid_type,
178+
const uint8_t *addr,
179+
size_t addr_len,
180+
uint16_t arp_type,
181+
usec_t llt_time,
182+
bool test_mode,
183+
struct duid *ret_duid,
184+
size_t *ret_len) {
185+
186+
switch (duid_type) {
187+
case DUID_TYPE_LLT:
188+
return dhcp_identifier_set_duid_llt(addr, addr_len, arp_type, llt_time, ret_duid, ret_len);
189+
case DUID_TYPE_EN:
190+
return dhcp_identifier_set_duid_en(test_mode, ret_duid, ret_len);
191+
case DUID_TYPE_LL:
192+
return dhcp_identifier_set_duid_ll(addr, addr_len, arp_type, ret_duid, ret_len);
193+
case DUID_TYPE_UUID:
194+
return dhcp_identifier_set_duid_uuid(ret_duid, ret_len);
195+
default:
196+
return -EINVAL;
197+
}
198+
}
199+
157200
int dhcp_identifier_set_iaid(
158201
int ifindex,
159202
const uint8_t *mac,
160203
size_t mac_len,
161204
bool legacy_unstable_byteorder,
162205
bool use_mac,
163-
void *_id) {
206+
void *ret) {
164207

165208
/* name is a pointer to memory in the sd_device struct, so must
166209
* have the same scope */
@@ -212,6 +255,6 @@ int dhcp_identifier_set_iaid(
212255
* behavior. */
213256
id32 = be32toh(id32);
214257

215-
unaligned_write_ne32(_id, id32);
258+
unaligned_write_ne32(ret, id32);
216259
return 0;
217260
}

src/libsystemd-network/dhcp-identifier.h

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,23 @@ struct duid {
5454
};
5555
} _packed_;
5656

57-
int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len, bool strict);
58-
int dhcp_identifier_set_duid_llt(struct duid *duid, usec_t t, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len);
59-
int dhcp_identifier_set_duid_ll(struct duid *duid, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len);
60-
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
61-
int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len);
62-
int dhcp_identifier_set_iaid(int ifindex, const uint8_t *mac, size_t mac_len, bool legacy_unstable_byteorder, bool use_mac, void *_id);
57+
int dhcp_validate_duid_len(DUIDType duid_type, size_t duid_len, bool strict);
58+
int dhcp_identifier_set_duid_en(bool test_mode, struct duid *ret_duid, size_t *ret_len);
59+
int dhcp_identifier_set_duid(
60+
DUIDType duid_type,
61+
const uint8_t *addr,
62+
size_t addr_len,
63+
uint16_t arp_type,
64+
usec_t llt_time,
65+
bool test_mode,
66+
struct duid *ret_duid,
67+
size_t *ret_len);
68+
int dhcp_identifier_set_iaid(
69+
int ifindex,
70+
const uint8_t *mac,
71+
size_t mac_len,
72+
bool legacy_unstable_byteorder,
73+
bool use_mac,
74+
void *ret);
75+
76+
const char *duid_type_to_string(DUIDType t) _const_;

0 commit comments

Comments
 (0)