summaryrefslogtreecommitdiff
path: root/src/network/networkd-link.c
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-02-04 23:13:52 +0100
committerTom Gundersen <teg@jklm.no>2014-02-07 15:48:35 +0100
commita6cc569e33a05b07550c6c7b4d67d83d868f8bc1 (patch)
tree5b8754fa594896f79ba4cb62772f6b1b49be4325 /src/network/networkd-link.c
parentd72143bad46b51fc0bbedf01ff92aea8b07afac6 (diff)
sd-dhcp-client: split sd_dhcp_lease from sd_dhcp_client
This allows us users of the library to keep copies of old leases. This is used by networkd to know what addresses to drop (if any) when the lease expires. In the future this may be used by DNAv4 and sd-dhcp-server.
Diffstat (limited to 'src/network/networkd-link.c')
-rw-r--r--src/network/networkd-link.c186
1 files changed, 111 insertions, 75 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 563eab9887..2883f195da 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -75,14 +75,8 @@ void link_free(Link *link) {
assert(link->manager);
- if (link->dhcp)
- sd_dhcp_client_free(link->dhcp);
-
- route_free(link->dhcp_route);
- link->dhcp_route = NULL;
-
- address_free(link->dhcp_address);
- link->dhcp_address = NULL;
+ sd_dhcp_client_free(link->dhcp_client);
+ sd_dhcp_lease_unref(link->dhcp_lease);
hashmap_remove(link->manager->links, &link->ifindex);
@@ -176,7 +170,7 @@ static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
}
static int link_enter_set_routes(Link *link) {
- Route *route;
+ Route *rt;
int r;
assert(link);
@@ -185,13 +179,13 @@ static int link_enter_set_routes(Link *link) {
link->state = LINK_STATE_SETTING_ROUTES;
- if (!link->network->static_routes && !link->dhcp_route)
+ if (!link->network->static_routes && !link->dhcp_lease)
return link_enter_configured(link);
log_debug_link(link, "setting routes");
- LIST_FOREACH(static_routes, route, link->network->static_routes) {
- r = route_configure(route, link, &route_handler);
+ LIST_FOREACH(static_routes, rt, link->network->static_routes) {
+ r = route_configure(rt, link, &route_handler);
if (r < 0) {
log_warning_link(link,
"could not set routes: %s", strerror(-r));
@@ -202,8 +196,28 @@ static int link_enter_set_routes(Link *link) {
link->route_messages ++;
}
- if (link->dhcp_route) {
- r = route_configure(link->dhcp_route, link, &route_handler);
+ if (link->dhcp_lease) {
+ _cleanup_route_free_ Route *route = NULL;
+ struct in_addr gateway;
+
+ r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
+ if (r < 0) {
+ log_warning_link(link, "DHCP error: no router: %s",
+ strerror(-r));
+ return r;
+ }
+
+ r = route_new_dynamic(&route);
+ if (r < 0) {
+ log_error_link(link, "Could not allocate route: %s",
+ strerror(-r));
+ return r;
+ }
+
+ route->family = AF_INET;
+ route->in_addr.in = gateway;
+
+ r = route_configure(route, link, &route_handler);
if (r < 0) {
log_warning_link(link,
"could not set routes: %s", strerror(-r));
@@ -249,7 +263,7 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
}
static int link_enter_set_addresses(Link *link) {
- Address *address;
+ Address *ad;
int r;
assert(link);
@@ -258,13 +272,13 @@ static int link_enter_set_addresses(Link *link) {
link->state = LINK_STATE_SETTING_ADDRESSES;
- if (!link->network->static_addresses && !link->dhcp_address)
+ if (!link->network->static_addresses && !link->dhcp_lease)
return link_enter_set_routes(link);
log_debug_link(link, "setting addresses");
- LIST_FOREACH(static_addresses, address, link->network->static_addresses) {
- r = address_configure(address, link, &address_handler);
+ LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
+ r = address_configure(ad, link, &address_handler);
if (r < 0) {
log_warning_link(link,
"could not set addresses: %s", strerror(-r));
@@ -275,8 +289,41 @@ static int link_enter_set_addresses(Link *link) {
link->addr_messages ++;
}
- if (link->dhcp_address) {
- r = address_configure(link->dhcp_address, link, &address_handler);
+ if (link->dhcp_lease) {
+ _cleanup_address_free_ Address *address = NULL;
+ struct in_addr addr;
+ struct in_addr netmask;
+ unsigned prefixlen;
+
+ r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
+ if (r < 0) {
+ log_warning_link(link, "DHCP error: no address: %s",
+ strerror(-r));
+ return r;
+ }
+
+ r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
+ if (r < 0) {
+ log_warning_link(link, "DHCP error: no netmask: %s",
+ strerror(-r));
+ return r;
+ }
+
+ prefixlen = net_netmask_to_prefixlen(&netmask);
+
+ r = address_new_dynamic(&address);
+ if (r < 0) {
+ log_error_link(link, "Could not allocate address: %s",
+ strerror(-r));
+ return r;
+ }
+
+ address->family = AF_INET;
+ address->in_addr.in = addr;
+ address->prefixlen = prefixlen;
+ address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
+
+ r = address_configure(address, link, &address_handler);
if (r < 0) {
log_warning_link(link,
"could not set addresses: %s", strerror(-r));
@@ -410,28 +457,33 @@ static int link_set_mtu(Link *link, uint32_t mtu) {
return 0;
}
-static int dhcp_lease_lost(sd_dhcp_client *client, Link *link) {
+static int dhcp_lease_lost(Link *link) {
+ _cleanup_address_free_ Address *address = NULL;
+ struct in_addr addr;
+ struct in_addr netmask;
+ unsigned prefixlen;
int r;
- assert(client);
assert(link);
+ assert(link->dhcp_lease);
- if (link->dhcp_address) {
- address_drop(link->dhcp_address, link, address_drop_handler);
+ r = address_new_dynamic(&address);
+ if (r >= 0) {
+ sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
+ sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
+ prefixlen = net_netmask_to_prefixlen(&netmask);
- address_free(link->dhcp_address);
- link->dhcp_address = NULL;
- }
+ address->family = AF_INET;
+ address->in_addr.in = addr;
+ address->prefixlen = prefixlen;
- if (link->dhcp_route) {
- route_free(link->dhcp_route);
- link->dhcp_route = NULL;
+ address_drop(address, link, address_drop_handler);
}
if (link->network->dhcp_mtu) {
uint16_t mtu;
- r = sd_dhcp_client_get_mtu(client, &mtu);
+ r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
if (r >= 0 && link->original_mtu != mtu) {
r = link_set_mtu(link, link->original_mtu);
if (r < 0) {
@@ -448,10 +500,13 @@ static int dhcp_lease_lost(sd_dhcp_client *client, Link *link) {
log_error("Failed to reset transient hostname");
}
+ link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
+
return 0;
}
static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
+ sd_dhcp_lease *lease;
struct in_addr address;
struct in_addr netmask;
struct in_addr gateway;
@@ -465,14 +520,21 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
assert(client);
assert(link);
- r = sd_dhcp_client_get_address(client, &address);
+ r = sd_dhcp_client_get_lease(client, &lease);
+ if (r < 0) {
+ log_warning_link(link, "DHCP error: no lease: %s",
+ strerror(-r));
+ return r;
+ }
+
+ r = sd_dhcp_lease_get_address(lease, &address);
if (r < 0) {
log_warning_link(link, "DHCP error: no address: %s",
strerror(-r));
return r;
}
- r = sd_dhcp_client_get_netmask(client, &netmask);
+ r = sd_dhcp_lease_get_netmask(lease, &netmask);
if (r < 0) {
log_warning_link(link, "DHCP error: no netmask: %s",
strerror(-r));
@@ -481,14 +543,13 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
prefixlen = net_netmask_to_prefixlen(&netmask);
- r = sd_dhcp_client_get_router(client, &gateway);
+ r = sd_dhcp_lease_get_router(lease, &gateway);
if (r < 0) {
log_warning_link(link, "DHCP error: no router: %s",
strerror(-r));
return r;
}
-
log_struct_link(LOG_INFO, link,
"MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
link->ifname,
@@ -503,35 +564,8 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
ADDRESS_FMT_VAL(gateway),
NULL);
- r = address_new_dynamic(&addr);
- if (r < 0) {
- log_error_link(link, "Could not allocate address: %s",
- strerror(-r));
- return r;
- }
-
- addr->family = AF_INET;
- addr->in_addr.in = address;
- addr->prefixlen = prefixlen;
- addr->broadcast.s_addr = address.s_addr | ~netmask.s_addr;
-
- r = route_new_dynamic(&rt);
- if (r < 0) {
- log_error_link(link, "Could not allocate route: %s",
- strerror(-r));
- return r;
- }
-
- rt->family = AF_INET;
- rt->in_addr.in = gateway;
-
- link->dhcp_address = addr;
- link->dhcp_route = rt;
- addr = NULL;
- rt = NULL;
-
if (link->network->dhcp_dns) {
- r = sd_dhcp_client_get_dns(client, &nameservers, &nameservers_size);
+ r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
if (r >= 0) {
r = manager_update_resolv_conf(link->manager);
if (r < 0)
@@ -542,7 +576,7 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
if (link->network->dhcp_mtu) {
uint16_t mtu;
- r = sd_dhcp_client_get_mtu(client, &mtu);
+ r = sd_dhcp_lease_get_mtu(lease, &mtu);
if (r >= 0) {
r = link_set_mtu(link, mtu);
if (r < 0)
@@ -554,7 +588,7 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
if (link->network->dhcp_hostname) {
const char *hostname;
- r = sd_dhcp_client_get_hostname(client, &hostname);
+ r = sd_dhcp_lease_get_hostname(lease, &hostname);
if (r >= 0) {
r = set_hostname(link->manager->bus, hostname);
if (r < 0)
@@ -563,6 +597,8 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
}
}
+ link->dhcp_lease = lease;
+
link_enter_set_addresses(link);
return 0;
@@ -592,7 +628,7 @@ static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
return;
}
- r = dhcp_lease_lost(client, link);
+ r = dhcp_lease_lost(link);
if (r < 0) {
link_enter_failed(link);
return;
@@ -634,29 +670,29 @@ static int link_acquire_conf(Link *link) {
assert(link->manager);
assert(link->manager->event);
- if (!link->dhcp) {
- r = sd_dhcp_client_new(&link->dhcp);
+ 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, NULL, 0);
+ r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
if (r < 0)
return r;
- r = sd_dhcp_client_set_index(link->dhcp, link->ifindex);
+ r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
if (r < 0)
return r;
- r = sd_dhcp_client_set_mac(link->dhcp, &link->mac);
+ r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
if (r < 0)
return r;
- r = sd_dhcp_client_set_callback(link->dhcp, dhcp_handler, link);
+ 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, 26);
+ r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
if (r < 0)
return r;
}
@@ -664,7 +700,7 @@ static int link_acquire_conf(Link *link) {
log_debug_link(link, "acquiring DHCPv4 lease");
- r = sd_dhcp_client_start(link->dhcp);
+ r = sd_dhcp_client_start(link->dhcp_client);
if (r < 0)
return r;
@@ -705,7 +741,7 @@ static int link_update_flags(Link *link, unsigned flags) {
log_info_link(link, "carrier off");
if (link->network->dhcp) {
- r = sd_dhcp_client_stop(link->dhcp);
+ r = sd_dhcp_client_stop(link->dhcp_client);
if (r < 0) {
log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
link_enter_failed(link);