+ assert(link);
+ assert(link->network);
+ assert(link->manager);
+
+ if (link->state == LINK_STATE_FAILED)
+ return;
+
+ switch (event) {
+ case DHCP_EVENT_NO_LEASE:
+ log_debug_link(link, "IP address in use.");
+ break;
+ case DHCP_EVENT_EXPIRED:
+ case DHCP_EVENT_STOP:
+ case DHCP_EVENT_IP_CHANGE:
+ if (link->network->dhcp_critical) {
+ log_error_link(link, "DHCPv4 connection considered system critical, "
+ "ignoring request to reconfigure it.");
+ return;
+ }
+
+ r = dhcp_lease_lost(link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return;
+ }
+
+ if (event == DHCP_EVENT_IP_CHANGE) {
+ r = dhcp_lease_acquired(client, link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return;
+ }
+ }
+
+ break;
+ case DHCP_EVENT_IP_ACQUIRE:
+ r = dhcp_lease_acquired(client, link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return;
+ }
+ break;
+ default:
+ if (event < 0)
+ log_warning_link(link, "DHCP error: %s", strerror(-event));
+ else
+ log_warning_link(link, "DHCP unknown event: %d", event);
+ break;
+ }
+
+ return;
+}
+
+static int link_acquire_conf(Link *link) {
+ int r;
+
+ assert(link);
+ assert(link->network);
+ assert(link->network->dhcp);
+ assert(link->manager);
+ assert(link->manager->event);
+
+ if (!link->dhcp_client) {
+ r = sd_dhcp_client_new(&link->dhcp_client);
+ if (r < 0)
+ return r;
+
+ r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
+ if (r < 0)
+ return r;
+
+ r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
+ if (r < 0)
+ return r;
+
+ r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
+ if (r < 0)
+ return r;
+
+ r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
+ if (r < 0)
+ return r;
+
+ if (link->network->dhcp_mtu) {
+ r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ log_debug_link(link, "acquiring DHCPv4 lease");
+
+ r = sd_dhcp_client_start(link->dhcp_client);