]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-dhcp4.c
networkd: address - factor out address_update()
[thirdparty/systemd.git] / src / network / networkd-dhcp4.c
CommitLineData
3c9b8860
TG
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013-2014 Tom Gundersen <teg@jklm.no>
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <netinet/ether.h>
23#include <linux/if.h>
24
958b66ea 25#include "hostname-util.h"
3c9b8860
TG
26#include "networkd-link.h"
27#include "network-internal.h"
28#include "dhcp-lease-internal.h"
29
1c4baffc 30static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m,
3c9b8860
TG
31 void *userdata) {
32 _cleanup_link_unref_ Link *link = userdata;
33 int r;
34
35 assert(link);
36 assert(link->dhcp4_messages);
37
38 link->dhcp4_messages --;
39
1c4baffc 40 r = sd_netlink_message_get_errno(m);
3c9b8860 41 if (r < 0 && r != -EEXIST) {
f6b8196f 42 log_link_error_errno(link, r, "Could not set DHCPv4 route: %m");
3c9b8860
TG
43 link_enter_failed(link);
44 }
45
46 if (!link->dhcp4_messages) {
47 link->dhcp4_configured = true;
8012cd39 48 link_check_ready(link);
3c9b8860
TG
49 }
50
51 return 1;
52}
53
54static int link_set_dhcp_routes(Link *link) {
55 struct in_addr gateway;
56 struct sd_dhcp_route *static_routes;
57 int r, n, i;
58
59 assert(link);
60 assert(link->dhcp_lease);
61
62 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
397d15fd 63 if (r < 0 && r != -ENODATA)
f6b8196f
LP
64 return log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m");
65
3c9b8860 66 if (r >= 0) {
46b0c76e 67 struct in_addr address;
3c9b8860
TG
68 _cleanup_route_free_ Route *route = NULL;
69 _cleanup_route_free_ Route *route_gw = NULL;
70
46b0c76e 71 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
f6b8196f
LP
72 if (r < 0)
73 return log_link_warning_errno(link, r, "DHCP error: could not get address: %m");
46b0c76e 74
f0213e37 75 r = route_new(&route, RTPROT_DHCP);
f6b8196f
LP
76 if (r < 0)
77 return log_link_error_errno(link, r, "Could not allocate route: %m");
3c9b8860 78
f0213e37 79 r = route_new(&route_gw, RTPROT_DHCP);
f6b8196f
LP
80 if (r < 0)
81 return log_link_error_errno(link, r, "Could not allocate route: %m");
3c9b8860
TG
82
83 /* The dhcp netmask may mask out the gateway. Add an explicit
84 * route for the gw host so that we can route no matter the
85 * netmask or existing kernel route tables. */
86 route_gw->family = AF_INET;
87 route_gw->dst_addr.in = gateway;
88 route_gw->dst_prefixlen = 32;
46b0c76e 89 route_gw->prefsrc_addr.in = address;
3c9b8860 90 route_gw->scope = RT_SCOPE_LINK;
84b5b79a 91 route_gw->metrics = link->network->dhcp_route_metric;
3c9b8860
TG
92
93 r = route_configure(route_gw, link, &dhcp4_route_handler);
f6b8196f
LP
94 if (r < 0)
95 return log_link_warning_errno(link, r, "Could not set host route: %m");
3c9b8860
TG
96
97 link->dhcp4_messages ++;
98
99 route->family = AF_INET;
100 route->in_addr.in = gateway;
46b0c76e 101 route->prefsrc_addr.in = address;
84b5b79a 102 route->metrics = link->network->dhcp_route_metric;
3c9b8860
TG
103
104 r = route_configure(route, link, &dhcp4_route_handler);
105 if (r < 0) {
f6b8196f 106 log_link_warning_errno(link, r, "Could not set routes: %m");
3c9b8860
TG
107 link_enter_failed(link);
108 return r;
109 }
110
111 link->dhcp4_messages ++;
112 }
113
114 n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
397d15fd 115 if (n == -ENODATA)
3c9b8860 116 return 0;
f6b8196f
LP
117 if (n < 0)
118 return log_link_warning_errno(link, n, "DHCP error: could not get routes: %m");
3c9b8860
TG
119
120 for (i = 0; i < n; i++) {
121 _cleanup_route_free_ Route *route = NULL;
122
f0213e37 123 r = route_new(&route, RTPROT_DHCP);
f6b8196f
LP
124 if (r < 0)
125 return log_link_error_errno(link, r, "Could not allocate route: %m");
3c9b8860
TG
126
127 route->family = AF_INET;
128 route->in_addr.in = static_routes[i].gw_addr;
129 route->dst_addr.in = static_routes[i].dst_addr;
130 route->dst_prefixlen = static_routes[i].dst_prefixlen;
84b5b79a 131 route->metrics = link->network->dhcp_route_metric;
3c9b8860
TG
132
133 r = route_configure(route, link, &dhcp4_route_handler);
f6b8196f
LP
134 if (r < 0)
135 return log_link_warning_errno(link, r, "Could not set host route: %m");
3c9b8860
TG
136
137 link->dhcp4_messages ++;
138 }
139
140 return 0;
141}
142
143static int dhcp_lease_lost(Link *link) {
144 _cleanup_address_free_ Address *address = NULL;
145 struct in_addr addr;
146 struct in_addr netmask;
147 struct in_addr gateway;
f414a269 148 unsigned prefixlen = 0;
3c9b8860
TG
149 int r;
150
151 assert(link);
152 assert(link->dhcp_lease);
153
79008bdd 154 log_link_warning(link, "DHCP lease lost");
3c9b8860
TG
155
156 if (link->network->dhcp_routes) {
157 struct sd_dhcp_route *routes;
158 int n, i;
159
160 n = sd_dhcp_lease_get_routes(link->dhcp_lease, &routes);
161 if (n >= 0) {
162 for (i = 0; i < n; i++) {
163 _cleanup_route_free_ Route *route = NULL;
164
f0213e37 165 r = route_new(&route, RTPROT_UNSPEC);
3c9b8860
TG
166 if (r >= 0) {
167 route->family = AF_INET;
168 route->in_addr.in = routes[i].gw_addr;
169 route->dst_addr.in = routes[i].dst_addr;
170 route->dst_prefixlen = routes[i].dst_prefixlen;
171
91b5f997
TG
172 route_remove(route, link,
173 &link_route_remove_handler);
3c9b8860
TG
174 }
175 }
176 }
177 }
178
f0213e37 179 r = address_new(&address);
3c9b8860
TG
180 if (r >= 0) {
181 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
182 if (r >= 0) {
183 _cleanup_route_free_ Route *route_gw = NULL;
184 _cleanup_route_free_ Route *route = NULL;
185
f0213e37 186 r = route_new(&route_gw, RTPROT_UNSPEC);
3c9b8860
TG
187 if (r >= 0) {
188 route_gw->family = AF_INET;
189 route_gw->dst_addr.in = gateway;
190 route_gw->dst_prefixlen = 32;
191 route_gw->scope = RT_SCOPE_LINK;
192
91b5f997
TG
193 route_remove(route_gw, link,
194 &link_route_remove_handler);
3c9b8860
TG
195 }
196
f0213e37 197 r = route_new(&route, RTPROT_UNSPEC);
3c9b8860
TG
198 if (r >= 0) {
199 route->family = AF_INET;
200 route->in_addr.in = gateway;
201
91b5f997
TG
202 route_remove(route, link,
203 &link_route_remove_handler);
3c9b8860
TG
204 }
205 }
206
f414a269
TG
207 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
208 if (r >= 0) {
209 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
210 if (r >= 0)
211 prefixlen = in_addr_netmask_to_prefixlen(&netmask);
3c9b8860 212
f414a269
TG
213 address->family = AF_INET;
214 address->in_addr.in = addr;
215 address->prefixlen = prefixlen;
3c9b8860 216
91b5f997 217 address_remove(address, link, &link_address_remove_handler);
f414a269 218 }
3c9b8860
TG
219 }
220
221 if (link->network->dhcp_mtu) {
222 uint16_t mtu;
223
224 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
225 if (r >= 0 && link->original_mtu != mtu) {
226 r = link_set_mtu(link, link->original_mtu);
227 if (r < 0) {
79008bdd 228 log_link_warning(link,
3c9b8860
TG
229 "DHCP error: could not reset MTU");
230 link_enter_failed(link);
231 return r;
232 }
233 }
234 }
235
236 if (link->network->dhcp_hostname) {
237 const char *hostname = NULL;
238
dce391e7 239 if (link->network->hostname)
a7d0ef44 240 hostname = link->network->hostname;
dce391e7
LP
241 else
242 (void) sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
a7d0ef44 243
dce391e7
LP
244 if (hostname) {
245 /* If a hostname was set due to the lease, then unset it now. */
246 r = link_set_hostname(link, NULL);
3c9b8860 247 if (r < 0)
dce391e7 248 log_link_warning_errno(link, r, "Failed to reset transient hostname: %m");
3c9b8860
TG
249 }
250 }
251
252 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
253 link->dhcp4_configured = false;
254
255 return 0;
256}
257
1c4baffc 258static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m,
3c9b8860
TG
259 void *userdata) {
260 _cleanup_link_unref_ Link *link = userdata;
261 int r;
262
263 assert(link);
264
1c4baffc 265 r = sd_netlink_message_get_errno(m);
3c9b8860 266 if (r < 0 && r != -EEXIST) {
f6b8196f 267 log_link_error_errno(link, r, "Could not set DHCPv4 address: %m");
3c9b8860 268 link_enter_failed(link);
45af44d4 269 } else if (r >= 0)
200a0868 270 manager_rtnl_process_address(rtnl, m, link->manager);
3c9b8860
TG
271
272 link_set_dhcp_routes(link);
273
274 return 1;
275}
276
277static int dhcp4_update_address(Link *link,
278 struct in_addr *address,
279 struct in_addr *netmask,
280 uint32_t lifetime) {
281 _cleanup_address_free_ Address *addr = NULL;
282 unsigned prefixlen;
283 int r;
284
285 assert(address);
286 assert(netmask);
287 assert(lifetime);
288
289 prefixlen = in_addr_netmask_to_prefixlen(netmask);
290
f0213e37 291 r = address_new(&addr);
3c9b8860
TG
292 if (r < 0)
293 return r;
294
295 addr->family = AF_INET;
296 addr->in_addr.in.s_addr = address->s_addr;
297 addr->cinfo.ifa_prefered = lifetime;
298 addr->cinfo.ifa_valid = lifetime;
299 addr->prefixlen = prefixlen;
300 addr->broadcast.s_addr = address->s_addr | ~netmask->s_addr;
301
36c32f61 302 /* use change rather than configure so that we will update the
3c9b8860 303 * lifetime of an existing address if it has already been configured */
36c32f61 304 r = address_change(addr, link, &dhcp4_address_handler);
3c9b8860
TG
305 if (r < 0)
306 return r;
307
308 return 0;
309}
310
311static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
312 sd_dhcp_lease *lease;
313 struct in_addr address;
314 struct in_addr netmask;
315 uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
316 int r;
317
318 assert(link);
319 assert(client);
320 assert(link->network);
321
322 r = sd_dhcp_client_get_lease(client, &lease);
f6b8196f
LP
323 if (r < 0)
324 return log_link_warning_errno(link, r, "DHCP error: no lease: %m");
3c9b8860
TG
325
326 sd_dhcp_lease_unref(link->dhcp_lease);
327 link->dhcp4_configured = false;
e6b18ffa 328 link->dhcp_lease = sd_dhcp_lease_ref(lease);
3c9b8860
TG
329
330 r = sd_dhcp_lease_get_address(lease, &address);
f6b8196f
LP
331 if (r < 0)
332 return log_link_warning_errno(link, r, "DHCP error: no address: %m");
3c9b8860
TG
333
334 r = sd_dhcp_lease_get_netmask(lease, &netmask);
f6b8196f
LP
335 if (r < 0)
336 return log_link_warning_errno(link, r, "DHCP error: no netmask: %m");
3c9b8860
TG
337
338 if (!link->network->dhcp_critical) {
f6b8196f
LP
339 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, &lifetime);
340 if (r < 0)
341 return log_link_warning_errno(link, r, "DHCP error: no lifetime: %m");
3c9b8860
TG
342 }
343
344 r = dhcp4_update_address(link, &address, &netmask, lifetime);
345 if (r < 0) {
f6b8196f 346 log_link_warning_errno(link, r, "Could not update IP address: %m");
3c9b8860
TG
347 link_enter_failed(link);
348 return r;
349 }
350
351 return 0;
352}
353
354static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
355 sd_dhcp_lease *lease;
356 struct in_addr address;
357 struct in_addr netmask;
358 struct in_addr gateway;
359 unsigned prefixlen;
360 uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
361 int r;
362
363 assert(client);
364 assert(link);
365
366 r = sd_dhcp_client_get_lease(client, &lease);
f2341e0a 367 if (r < 0)
f6b8196f 368 return log_link_error_errno(link, r, "DHCP error: No lease: %m");
3c9b8860
TG
369
370 r = sd_dhcp_lease_get_address(lease, &address);
f2341e0a 371 if (r < 0)
f6b8196f 372 return log_link_error_errno(link, r, "DHCP error: No address: %m");
3c9b8860
TG
373
374 r = sd_dhcp_lease_get_netmask(lease, &netmask);
f2341e0a 375 if (r < 0)
f6b8196f 376 return log_link_error_errno(link, r, "DHCP error: No netmask: %m");
3c9b8860
TG
377
378 prefixlen = in_addr_netmask_to_prefixlen(&netmask);
379
380 r = sd_dhcp_lease_get_router(lease, &gateway);
397d15fd 381 if (r < 0 && r != -ENODATA)
f6b8196f 382 return log_link_error_errno(link, r, "DHCP error: Could not get gateway: %m");
3c9b8860
TG
383
384 if (r >= 0)
f2341e0a
LP
385 log_struct(LOG_INFO,
386 LOG_LINK_INTERFACE(link),
387 LOG_LINK_MESSAGE(link, "DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
388 ADDRESS_FMT_VAL(address),
389 prefixlen,
390 ADDRESS_FMT_VAL(gateway)),
391 "ADDRESS=%u.%u.%u.%u", ADDRESS_FMT_VAL(address),
392 "PREFIXLEN=%u", prefixlen,
393 "GATEWAY=%u.%u.%u.%u", ADDRESS_FMT_VAL(gateway),
394 NULL);
3c9b8860 395 else
f2341e0a
LP
396 log_struct(LOG_INFO,
397 LOG_LINK_INTERFACE(link),
398 LOG_LINK_MESSAGE(link, "DHCPv4 address %u.%u.%u.%u/%u",
399 ADDRESS_FMT_VAL(address),
400 prefixlen),
401 "ADDRESS=%u.%u.%u.%u", ADDRESS_FMT_VAL(address),
402 "PREFIXLEN=%u", prefixlen,
403 NULL);
3c9b8860 404
e6b18ffa 405 link->dhcp_lease = sd_dhcp_lease_ref(lease);
3c9b8860
TG
406
407 if (link->network->dhcp_mtu) {
408 uint16_t mtu;
409
410 r = sd_dhcp_lease_get_mtu(lease, &mtu);
411 if (r >= 0) {
412 r = link_set_mtu(link, mtu);
413 if (r < 0)
f2341e0a 414 log_link_error_errno(link, r, "Failed to set MTU to %" PRIu16 ": %m", mtu);
3c9b8860
TG
415 }
416 }
417
418 if (link->network->dhcp_hostname) {
49f6e11e 419 const char *hostname = NULL;
3c9b8860 420
dce391e7 421 if (link->network->hostname)
a7d0ef44 422 hostname = link->network->hostname;
dce391e7
LP
423 else
424 (void) sd_dhcp_lease_get_hostname(lease, &hostname);
a7d0ef44 425
dce391e7 426 if (hostname) {
3c9b8860
TG
427 r = link_set_hostname(link, hostname);
428 if (r < 0)
f2341e0a 429 log_link_error_errno(link, r, "Failed to set transient hostname to '%s': %m", hostname);
3c9b8860
TG
430 }
431 }
432
21b80ad1
LP
433 if (link->network->dhcp_timezone) {
434 const char *tz = NULL;
435
436 (void) sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
437
438 if (tz) {
439 r = link_set_timezone(link, tz);
440 if (r < 0)
441 log_link_error_errno(link, r, "Failed to set timezone to '%s': %m", tz);
442 }
443 }
444
3c9b8860 445 if (!link->network->dhcp_critical) {
f2341e0a 446 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, &lifetime);
3c9b8860 447 if (r < 0) {
f2341e0a 448 log_link_warning_errno(link, r, "DHCP error: no lifetime: %m");
3c9b8860
TG
449 return r;
450 }
451 }
452
453 r = dhcp4_update_address(link, &address, &netmask, lifetime);
454 if (r < 0) {
f2341e0a 455 log_link_warning_errno(link, r, "Could not update IP address: %m");
3c9b8860
TG
456 link_enter_failed(link);
457 return r;
458 }
459
460 return 0;
461}
462static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
463 Link *link = userdata;
464 int r = 0;
465
466 assert(link);
467 assert(link->network);
468 assert(link->manager);
469
470 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
471 return;
472
473 switch (event) {
03748142
DH
474 case SD_DHCP_CLIENT_EVENT_EXPIRED:
475 case SD_DHCP_CLIENT_EVENT_STOP:
476 case SD_DHCP_CLIENT_EVENT_IP_CHANGE:
3c9b8860 477 if (link->network->dhcp_critical) {
f6b8196f 478 log_link_error(link, "DHCPv4 connection considered system critical, ignoring request to reconfigure it.");
3c9b8860
TG
479 return;
480 }
481
482 if (link->dhcp_lease) {
483 r = dhcp_lease_lost(link);
484 if (r < 0) {
485 link_enter_failed(link);
486 return;
487 }
488 }
489
03748142 490 if (event == SD_DHCP_CLIENT_EVENT_IP_CHANGE) {
3c9b8860
TG
491 r = dhcp_lease_acquired(client, link);
492 if (r < 0) {
493 link_enter_failed(link);
494 return;
495 }
496 }
497
498 break;
03748142 499 case SD_DHCP_CLIENT_EVENT_RENEW:
3c9b8860
TG
500 r = dhcp_lease_renew(client, link);
501 if (r < 0) {
502 link_enter_failed(link);
503 return;
504 }
505 break;
03748142 506 case SD_DHCP_CLIENT_EVENT_IP_ACQUIRE:
3c9b8860
TG
507 r = dhcp_lease_acquired(client, link);
508 if (r < 0) {
509 link_enter_failed(link);
510 return;
511 }
512 break;
513 default:
514 if (event < 0)
f6b8196f 515 log_link_warning_errno(link, event, "DHCP error: Client failed: %m");
3c9b8860 516 else
f6b8196f 517 log_link_warning(link, "DHCP unknown event: %i", event);
3c9b8860
TG
518 break;
519 }
520
521 return;
522}
523
524int dhcp4_configure(Link *link) {
525 int r;
526
527 assert(link);
528 assert(link->network);
e0ee46f2 529 assert(link->network->dhcp & ADDRESS_FAMILY_IPV4);
3c9b8860
TG
530
531 r = sd_dhcp_client_new(&link->dhcp_client);
532 if (r < 0)
533 return r;
534
535 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
536 if (r < 0)
537 return r;
538
76253e73
DW
539 r = sd_dhcp_client_set_mac(link->dhcp_client,
540 (const uint8_t *) &link->mac,
541 sizeof (link->mac), ARPHRD_ETHER);
3c9b8860
TG
542 if (r < 0)
543 return r;
544
545 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
546 if (r < 0)
547 return r;
548
549 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
550 if (r < 0)
551 return r;
552
553 r = sd_dhcp_client_set_request_broadcast(link->dhcp_client,
554 link->network->dhcp_broadcast);
555 if (r < 0)
556 return r;
557
558 if (link->mtu) {
559 r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
560 if (r < 0)
561 return r;
562 }
563
564 if (link->network->dhcp_mtu) {
39745a5a
LP
565 r = sd_dhcp_client_set_request_option(link->dhcp_client,
566 DHCP_OPTION_INTERFACE_MTU);
567 if (r < 0)
568 return r;
3c9b8860
TG
569 }
570
571 if (link->network->dhcp_routes) {
572 r = sd_dhcp_client_set_request_option(link->dhcp_client,
573 DHCP_OPTION_STATIC_ROUTE);
574 if (r < 0)
575 return r;
576 r = sd_dhcp_client_set_request_option(link->dhcp_client,
577 DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
7d6884b6
TA
578 if (r < 0)
579 return r;
3c9b8860
TG
580 }
581
4b7b5abb
LP
582 /* Always acquire the timezone and NTP*/
583 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_NTP_SERVER);
584 if (r < 0)
585 return r;
586
8eb9058d
LP
587 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_NEW_TZDB_TIMEZONE);
588 if (r < 0)
589 return r;
590
3c9b8860
TG
591 if (link->network->dhcp_sendhost) {
592 _cleanup_free_ char *hostname = NULL;
a7d0ef44
SS
593 const char *hn = NULL;
594
595 if (!link->network->hostname) {
596 hostname = gethostname_malloc();
597 if (!hostname)
598 return -ENOMEM;
3c9b8860 599
a7d0ef44
SS
600 hn = hostname;
601 } else
602 hn = link->network->hostname;
3c9b8860 603
a7d0ef44
SS
604 if (!is_localhost(hn)) {
605 r = sd_dhcp_client_set_hostname(link->dhcp_client, hn);
3c9b8860
TG
606 if (r < 0)
607 return r;
608 }
609 }
610
611 if (link->network->dhcp_vendor_class_identifier) {
612 r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
613 link->network->dhcp_vendor_class_identifier);
614 if (r < 0)
615 return r;
616 }
617
3e43b2cd
JJ
618 switch (link->network->dhcp_client_identifier) {
619 case DHCP_CLIENT_ID_DUID:
620 /* Library defaults to this. */
621 break;
622 case DHCP_CLIENT_ID_MAC:
623 r = sd_dhcp_client_set_client_id(link->dhcp_client,
624 ARPHRD_ETHER,
625 (const uint8_t *) &link->mac,
626 sizeof (link->mac));
627 if (r < 0)
628 return r;
629 break;
630 default:
631 assert_not_reached("Unknown client identifier type.");
632 }
633
3c9b8860
TG
634 return 0;
635}