Skip to content

Commit c07aead

Browse files
committed
networkd: dhcp - refactor handler
1 parent c3ab238 commit c07aead

File tree

1 file changed

+168
-126
lines changed

1 file changed

+168
-126
lines changed

src/network/networkd-link.c

Lines changed: 168 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -410,175 +410,217 @@ static int link_set_mtu(Link *link, uint32_t mtu) {
410410
return 0;
411411
}
412412

413-
static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
414-
Link *link = userdata;
415-
struct in_addr address;
416-
struct in_addr netmask;
417-
struct in_addr gateway;
418-
unsigned prefixlen;
413+
static int dhcp_lease_lost(sd_dhcp_client *client, Link *link) {
419414
int r;
420415

416+
assert(client);
421417
assert(link);
422-
assert(link->network);
423-
assert(link->manager);
424418

425-
if (link->state == LINK_STATE_FAILED)
426-
return;
419+
if (link->dhcp_address) {
420+
address_drop(link->dhcp_address, link, address_drop_handler);
427421

428-
if (event < 0) {
429-
log_warning_link(link, "DHCP error: %s", strerror(-event));
430-
link_enter_failed(link);
431-
return;
422+
address_free(link->dhcp_address);
423+
link->dhcp_address = NULL;
432424
}
433425

434-
if (event == DHCP_EVENT_NO_LEASE)
435-
log_debug_link(link, "IP address in use.");
436-
437-
if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_EXPIRED ||
438-
event == DHCP_EVENT_STOP) {
439-
if (link->network->dhcp_critical) {
440-
log_warning_link(link, "DHCPv4 connection considered system critical, "
441-
"ignoring request to reconfigure it down.");
442-
return;
443-
}
426+
if (link->dhcp_route) {
427+
route_free(link->dhcp_route);
428+
link->dhcp_route = NULL;
429+
}
444430

445-
if (link->dhcp_address) {
446-
address_drop(link->dhcp_address, link, address_drop_handler);
431+
if (link->network->dhcp_mtu) {
432+
uint16_t mtu;
447433

448-
address_free(link->dhcp_address);
449-
link->dhcp_address = NULL;
434+
r = sd_dhcp_client_get_mtu(client, &mtu);
435+
if (r >= 0 && link->original_mtu != mtu) {
436+
r = link_set_mtu(link, link->original_mtu);
437+
if (r < 0) {
438+
log_warning_link(link, "DHCP error: could not reset MTU");
439+
link_enter_failed(link);
440+
return r;
441+
}
450442
}
443+
}
451444

452-
if (link->dhcp_route) {
453-
route_free(link->dhcp_route);
454-
link->dhcp_route = NULL;
455-
}
445+
if (link->network->dhcp_hostname) {
446+
r = set_hostname(link->manager->bus, "");
447+
if (r < 0)
448+
log_error("Failed to reset transient hostname");
449+
}
456450

457-
if (link->network->dhcp_mtu) {
458-
uint16_t mtu;
451+
return 0;
452+
}
459453

460-
r = sd_dhcp_client_get_mtu(client, &mtu);
461-
if (r >= 0 && link->original_mtu != mtu) {
462-
r = link_set_mtu(link, link->original_mtu);
463-
if (r < 0) {
464-
log_warning_link(link, "DHCP error: could not reset MTU");
465-
link_enter_failed(link);
466-
return;
467-
}
468-
}
469-
}
454+
static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
455+
struct in_addr address;
456+
struct in_addr netmask;
457+
struct in_addr gateway;
458+
unsigned prefixlen;
459+
_cleanup_address_free_ Address *addr = NULL;
460+
_cleanup_route_free_ Route *rt = NULL;
461+
struct in_addr *nameservers;
462+
size_t nameservers_size;
463+
int r;
470464

471-
if (link->network->dhcp_hostname) {
472-
r = set_hostname(link->manager->bus, "");
473-
if (r < 0)
474-
log_error("Failed to reset transient hostname");
475-
}
476-
}
465+
assert(client);
466+
assert(link);
477467

478468
r = sd_dhcp_client_get_address(client, &address);
479469
if (r < 0) {
480-
log_warning_link(link, "DHCP error: no address");
481-
link_enter_failed(link);
482-
return;
470+
log_warning_link(link, "DHCP error: no address: %s",
471+
strerror(-r));
472+
return r;
483473
}
484474

485475
r = sd_dhcp_client_get_netmask(client, &netmask);
486476
if (r < 0) {
487-
log_warning_link(link, "DHCP error: no netmask");
488-
link_enter_failed(link);
489-
return;
477+
log_warning_link(link, "DHCP error: no netmask: %s",
478+
strerror(-r));
479+
return r;
490480
}
491481

492482
prefixlen = net_netmask_to_prefixlen(&netmask);
493483

494484
r = sd_dhcp_client_get_router(client, &gateway);
495485
if (r < 0) {
496-
log_warning_link(link, "DHCP error: no router");
497-
link_enter_failed(link);
498-
return;
486+
log_warning_link(link, "DHCP error: no router: %s",
487+
strerror(-r));
488+
return r;
499489
}
500490

501-
if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_IP_ACQUIRE) {
502-
_cleanup_address_free_ Address *addr = NULL;
503-
_cleanup_route_free_ Route *rt = NULL;
504-
struct in_addr *nameservers;
505-
size_t nameservers_size;
506-
507-
log_struct_link(LOG_INFO, link,
508-
"MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
509-
link->ifname,
510-
ADDRESS_FMT_VAL(address),
511-
prefixlen,
512-
ADDRESS_FMT_VAL(gateway),
513-
"ADDRESS=%u.%u.%u.%u",
514-
ADDRESS_FMT_VAL(address),
515-
"PREFIXLEN=%u",
516-
prefixlen,
517-
"GATEWAY=%u.%u.%u.%u",
518-
ADDRESS_FMT_VAL(gateway),
519-
NULL);
520491

521-
r = address_new_dynamic(&addr);
522-
if (r < 0) {
523-
log_error_link(link, "Could not allocate address");
524-
link_enter_failed(link);
525-
return;
526-
}
492+
log_struct_link(LOG_INFO, link,
493+
"MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
494+
link->ifname,
495+
ADDRESS_FMT_VAL(address),
496+
prefixlen,
497+
ADDRESS_FMT_VAL(gateway),
498+
"ADDRESS=%u.%u.%u.%u",
499+
ADDRESS_FMT_VAL(address),
500+
"PREFIXLEN=%u",
501+
prefixlen,
502+
"GATEWAY=%u.%u.%u.%u",
503+
ADDRESS_FMT_VAL(gateway),
504+
NULL);
527505

528-
addr->family = AF_INET;
529-
addr->in_addr.in = address;
530-
addr->prefixlen = prefixlen;
531-
addr->broadcast.s_addr = address.s_addr | ~netmask.s_addr;
506+
r = address_new_dynamic(&addr);
507+
if (r < 0) {
508+
log_error_link(link, "Could not allocate address: %s",
509+
strerror(-r));
510+
return r;
511+
}
532512

533-
r = route_new_dynamic(&rt);
534-
if (r < 0) {
535-
log_error_link(link, "Could not allocate route");
536-
link_enter_failed(link);
537-
return;
513+
addr->family = AF_INET;
514+
addr->in_addr.in = address;
515+
addr->prefixlen = prefixlen;
516+
addr->broadcast.s_addr = address.s_addr | ~netmask.s_addr;
517+
518+
r = route_new_dynamic(&rt);
519+
if (r < 0) {
520+
log_error_link(link, "Could not allocate route: %s",
521+
strerror(-r));
522+
return r;
523+
}
524+
525+
rt->family = AF_INET;
526+
rt->in_addr.in = gateway;
527+
528+
link->dhcp_address = addr;
529+
link->dhcp_route = rt;
530+
addr = NULL;
531+
rt = NULL;
532+
533+
if (link->network->dhcp_dns) {
534+
r = sd_dhcp_client_get_dns(client, &nameservers, &nameservers_size);
535+
if (r >= 0) {
536+
r = manager_update_resolv_conf(link->manager);
537+
if (r < 0)
538+
log_error("Failed to update resolv.conf");
538539
}
540+
}
541+
542+
if (link->network->dhcp_mtu) {
543+
uint16_t mtu;
539544

540-
rt->family = AF_INET;
541-
rt->in_addr.in = gateway;
545+
r = sd_dhcp_client_get_mtu(client, &mtu);
546+
if (r >= 0) {
547+
r = link_set_mtu(link, mtu);
548+
if (r < 0)
549+
log_error_link(link, "Failed to set MTU "
550+
"to %" PRIu16, mtu);
551+
}
552+
}
542553

543-
link->dhcp_address = addr;
544-
link->dhcp_route = rt;
545-
addr = NULL;
546-
rt = NULL;
554+
if (link->network->dhcp_hostname) {
555+
const char *hostname;
547556

548-
if (link->network->dhcp_dns) {
549-
r = sd_dhcp_client_get_dns(client, &nameservers, &nameservers_size);
550-
if (r >= 0) {
551-
r = manager_update_resolv_conf(link->manager);
552-
if (r < 0)
553-
log_error("Failed to update resolv.conf");
554-
}
557+
r = sd_dhcp_client_get_hostname(client, &hostname);
558+
if (r >= 0) {
559+
r = set_hostname(link->manager->bus, hostname);
560+
if (r < 0)
561+
log_error("Failed to set transient hostname "
562+
"to '%s'", hostname);
555563
}
564+
}
556565

557-
if (link->network->dhcp_mtu) {
558-
uint16_t mtu;
559-
560-
r = sd_dhcp_client_get_mtu(client, &mtu);
561-
if (r >= 0) {
562-
r = link_set_mtu(link, mtu);
563-
if (r < 0)
564-
log_error_link(link, "Failed to set MTU "
565-
"to %" PRIu16, mtu);
566+
link_enter_set_addresses(link);
567+
568+
return 0;
569+
}
570+
571+
static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
572+
Link *link = userdata;
573+
int r;
574+
575+
assert(link);
576+
assert(link->network);
577+
assert(link->manager);
578+
579+
if (link->state == LINK_STATE_FAILED)
580+
return;
581+
582+
switch (event) {
583+
case DHCP_EVENT_NO_LEASE:
584+
log_debug_link(link, "IP address in use.");
585+
break;
586+
case DHCP_EVENT_EXPIRED:
587+
case DHCP_EVENT_STOP:
588+
case DHCP_EVENT_IP_CHANGE:
589+
if (link->network->dhcp_critical) {
590+
log_error_link(link, "DHCPv4 connection considered system critical, "
591+
"ignoring request to reconfigure it.");
592+
return;
566593
}
567-
}
568594

569-
if (link->network->dhcp_hostname) {
570-
const char *hostname;
595+
r = dhcp_lease_lost(client, link);
596+
if (r < 0) {
597+
link_enter_failed(link);
598+
return;
599+
}
571600

572-
r = sd_dhcp_client_get_hostname(client, &hostname);
573-
if (r >= 0) {
574-
r = set_hostname(link->manager->bus, hostname);
575-
if (r < 0)
576-
log_error("Failed to set transient hostname "
577-
"to '%s'", hostname);
601+
if (event == DHCP_EVENT_IP_CHANGE) {
602+
r = dhcp_lease_acquired(client, link);
603+
if (r < 0) {
604+
link_enter_failed(link);
605+
return;
606+
}
578607
}
579-
}
580608

581-
link_enter_set_addresses(link);
609+
break;
610+
case DHCP_EVENT_IP_ACQUIRE:
611+
r = dhcp_lease_acquired(client, link);
612+
if (r < 0) {
613+
link_enter_failed(link);
614+
return;
615+
}
616+
break;
617+
default:
618+
if (event < 0)
619+
log_warning_link(link, "DHCP error: %s", strerror(-event));
620+
else
621+
log_warning_link(link, "DHCP unknown event: %d", event);
622+
link_enter_failed(link);
623+
break;
582624
}
583625

584626
return;

0 commit comments

Comments
 (0)