ell.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] dhcp-server: Add API for manipulating leases
@ 2021-07-19 14:00 Andrew Zaborowski
  2021-07-19 14:00 ` [PATCH 2/2] dhcp-server: Time out lease offers Andrew Zaborowski
  2021-07-22 16:36 ` [PATCH 1/2] dhcp-server: Add API for manipulating leases Denis Kenzior
  0 siblings, 2 replies; 3+ messages in thread
From: Andrew Zaborowski @ 2021-07-19 14:00 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 5865 bytes --]

Add methods for obtaining and releasing DHCP leases.  There are four
methods that correspond to the DISCOVER, REQUEST, DECLINE and RELEASE
messages and two shortcut methods for releasing the leases.  This API is
useful for implementing mechanisms like the optional P2P IP Allocation
in the 802.11 4-Way Handshake and FILS IP Address Allocation in 802.11
Associate frames (both reduces the number of roundtrips in connection
setup).  Since there are multiple such mechanisms I decided to include
discover and request as separate methods to allow more flexibility.
---
 ell/dhcp-server.c | 106 +++++++++++++++++++++++++++++++++++++++++++++-
 ell/dhcp.h        |  15 +++++++
 ell/ell.sym       |   6 +++
 3 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/ell/dhcp-server.c b/ell/dhcp-server.c
index ecdd612..fa5a7db 100644
--- a/ell/dhcp-server.c
+++ b/ell/dhcp-server.c
@@ -126,12 +126,14 @@ static struct l_dhcp_lease *find_lease_by_mac(struct l_dhcp_server *server,
 	return l_queue_find(server->lease_list, match_lease_mac, mac);
 }
 
-static void remove_lease(struct l_dhcp_server *server,
+static bool remove_lease(struct l_dhcp_server *server,
 				struct l_dhcp_lease *lease)
 {
-	l_queue_remove(server->lease_list, lease);
+	if (!l_queue_remove(server->lease_list, lease))
+		return false;
 
 	_dhcp_lease_free(lease);
+	return true;
 }
 
 /* Clear the old lease and create the new one */
@@ -1042,3 +1044,103 @@ failed:
 	l_free(dns_list);
 	return false;
 }
+
+LIB_EXPORT struct l_dhcp_lease *l_dhcp_server_discover(
+						struct l_dhcp_server *server,
+						uint32_t requested_ip_opt,
+						const uint8_t *mac)
+{
+	struct l_dhcp_lease *lease;
+
+	SERVER_DEBUG("Requested IP " NIPQUAD_FMT " for " MAC,
+			NIPQUAD(requested_ip_opt), MAC_STR(mac));
+
+	if ((lease = find_lease_by_mac(server, mac)))
+		requested_ip_opt = lease->address;
+	else if (!check_requested_ip(server, requested_ip_opt)) {
+		requested_ip_opt = find_free_or_expired_ip(server, mac);
+
+		if (unlikely(!requested_ip_opt)) {
+			SERVER_DEBUG("Could not find any free addresses");
+			return NULL;
+		}
+	}
+
+	lease = add_lease(server, true, mac, requested_ip_opt);
+	if (unlikely(!lease)) {
+		SERVER_DEBUG("add_lease() failed");
+		return NULL;
+	}
+
+	SERVER_DEBUG("Offering " NIPQUAD_FMT " to " MAC,
+			NIPQUAD(requested_ip_opt), MAC_STR(mac));
+	return lease;
+}
+
+LIB_EXPORT bool l_dhcp_server_request(struct l_dhcp_server *server,
+					struct l_dhcp_lease *lease)
+{
+	if (unlikely(!lease))
+		return false;
+
+	SERVER_DEBUG("Requested IP " NIPQUAD_FMT " for " MAC,
+			NIPQUAD(lease->address), MAC_STR(lease->mac));
+
+	lease = add_lease(server, false, lease->mac, lease->address);
+
+	if (server->event_handler)
+		server->event_handler(server, L_DHCP_SERVER_EVENT_NEW_LEASE,
+					server->user_data, lease);
+
+	return true;
+}
+
+LIB_EXPORT bool l_dhcp_server_decline(struct l_dhcp_server *server,
+					struct l_dhcp_lease *lease)
+{
+	if (unlikely(!lease || !lease->offering))
+		return false;
+
+	SERVER_DEBUG("Declined IP " NIPQUAD_FMT " for " MAC,
+			NIPQUAD(lease->address), MAC_STR(lease->mac));
+
+	return remove_lease(server, lease);
+}
+
+LIB_EXPORT bool l_dhcp_server_release(struct l_dhcp_server *server,
+					struct l_dhcp_lease *lease)
+{
+	if (unlikely(!lease || lease->offering))
+		return false;
+
+	SERVER_DEBUG("Released IP " NIPQUAD_FMT " for " MAC,
+			NIPQUAD(lease->address), MAC_STR(lease->mac));
+
+	lease_release(server, lease);
+	return true;
+}
+
+/* Drop an offered, active or expired lease without moving it to expired_list */
+LIB_EXPORT bool l_dhcp_server_lease_remove(struct l_dhcp_server *server,
+						struct l_dhcp_lease *lease)
+{
+	if (unlikely(!lease))
+		return false;
+
+	if (unlikely(!l_queue_remove(server->lease_list, lease) &&
+			!l_queue_remove(server->expired_list, lease)))
+		return false;
+
+	_dhcp_lease_free(lease);
+	set_next_expire_timer(server, NULL);
+	return true;
+}
+
+LIB_EXPORT void l_dhcp_server_expire_by_mac(struct l_dhcp_server *server,
+						const uint8_t *mac)
+{
+	struct l_dhcp_lease *lease = find_lease_by_mac(server, mac);
+
+	if (likely(lease))
+		lease_release(server, lease);
+}
diff --git a/ell/dhcp.h b/ell/dhcp.h
index 2af75cc..2804c78 100644
--- a/ell/dhcp.h
+++ b/ell/dhcp.h
@@ -141,6 +141,21 @@ bool l_dhcp_server_set_ip_address(struct l_dhcp_server *server,
 bool l_dhcp_server_set_netmask(struct l_dhcp_server *server, const char *mask);
 bool l_dhcp_server_set_gateway(struct l_dhcp_server *server, const char *ip);
 bool l_dhcp_server_set_dns(struct l_dhcp_server *server, char **dns);
+
+struct l_dhcp_lease *l_dhcp_server_discover(struct l_dhcp_server *server,
+						uint32_t requested_ip_opt,
+						const uint8_t *mac);
+bool l_dhcp_server_request(struct l_dhcp_server *server,
+				struct l_dhcp_lease *lease);
+bool l_dhcp_server_decline(struct l_dhcp_server *server,
+				struct l_dhcp_lease *lease);
+bool l_dhcp_server_release(struct l_dhcp_server *server,
+				struct l_dhcp_lease *lease);
+
+bool l_dhcp_server_lease_remove(struct l_dhcp_server *server,
+				struct l_dhcp_lease *lease);
+void l_dhcp_server_expire_by_mac(struct l_dhcp_server *server,
+					const uint8_t *mac);
 #ifdef __cplusplus
 }
 #endif
diff --git a/ell/ell.sym b/ell/ell.sym
index e5eeefb..4d41448 100644
--- a/ell/ell.sym
+++ b/ell/ell.sym
@@ -259,6 +259,12 @@ global:
 	l_dhcp_server_set_netmask;
 	l_dhcp_server_set_gateway;
 	l_dhcp_server_set_dns;
+	l_dhcp_server_discover;
+	l_dhcp_server_request;
+	l_dhcp_server_decline;
+	l_dhcp_server_release;
+	l_dhcp_server_lease_remove;
+	l_dhcp_server_lease_expire_by_mac;
 	/* dhcp6 */
 	l_dhcp6_client_new;
 	l_dhcp6_client_destroy;
-- 
2.30.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] dhcp-server: Time out lease offers
  2021-07-19 14:00 [PATCH 1/2] dhcp-server: Add API for manipulating leases Andrew Zaborowski
@ 2021-07-19 14:00 ` Andrew Zaborowski
  2021-07-22 16:36 ` [PATCH 1/2] dhcp-server: Add API for manipulating leases Denis Kenzior
  1 sibling, 0 replies; 3+ messages in thread
From: Andrew Zaborowski @ 2021-07-19 14:00 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 4628 bytes --]

Handle lease->lifetime for leases in the offering state just like the
active ones.  Add missing set_next_expire_timer calls.  Fix typos in
an add_lease comment that I'm moving.
---
 ell/dhcp-server.c | 68 ++++++++++++++++++++++++++---------------------
 1 file changed, 38 insertions(+), 30 deletions(-)

diff --git a/ell/dhcp-server.c b/ell/dhcp-server.c
index fa5a7db..bae0f10 100644
--- a/ell/dhcp-server.c
+++ b/ell/dhcp-server.c
@@ -126,16 +126,6 @@ static struct l_dhcp_lease *find_lease_by_mac(struct l_dhcp_server *server,
 	return l_queue_find(server->lease_list, match_lease_mac, mac);
 }
 
-static bool remove_lease(struct l_dhcp_server *server,
-				struct l_dhcp_lease *lease)
-{
-	if (!l_queue_remove(server->lease_list, lease))
-		return false;
-
-	_dhcp_lease_free(lease);
-	return true;
-}
-
 /* Clear the old lease and create the new one */
 static int get_lease(struct l_dhcp_server *server, uint32_t yiaddr,
 				const uint8_t *mac,
@@ -198,6 +188,9 @@ static void set_next_expire_timer(struct l_dhcp_server *server,
 					struct l_dhcp_lease *expired)
 {
 	struct l_dhcp_lease *next;
+	uint64_t expiry;
+	uint64_t now;
+	uint64_t next_timeout;
 
 	/*
 	 * If this is an expiring lease put it into the expired queue, removing
@@ -206,32 +199,35 @@ static void set_next_expire_timer(struct l_dhcp_server *server,
 	if (expired) {
 		l_queue_remove(server->lease_list, expired);
 
-		if (l_queue_length(server->expired_list) > server->max_expired)
-			_dhcp_lease_free(l_queue_pop_head(
+		if (!expired->offering) {
+			if (l_queue_length(server->expired_list) >
+					server->max_expired)
+				_dhcp_lease_free(l_queue_pop_head(
 							server->expired_list));
 
-		l_queue_push_tail(server->expired_list, expired);
+			l_queue_push_tail(server->expired_list, expired);
+		} else
+			_dhcp_lease_free(expired);
 	}
 
 	next = l_queue_peek_tail(server->lease_list);
-	if (!next || next->offering) {
+	if (!next) {
 		l_timeout_remove(server->next_expire);
 		server->next_expire = NULL;
 		return;
 	}
 
-	if (server->next_expire) {
-		uint64_t expiry = get_lease_expiry_time(next);
-		uint64_t now = l_time_now();
-		uint64_t next_timeout = l_time_after(expiry, now) ?
-			l_time_to_msecs(expiry - now) : 0;
+	expiry = get_lease_expiry_time(next);
+	now = l_time_now();
+	next_timeout = l_time_after(expiry, now) ?
+		l_time_to_msecs(expiry - now) : 0;
 
+	if (server->next_expire)
 		l_timeout_modify_ms(server->next_expire, next_timeout ?: 1);
-	} else
-		server->next_expire = l_timeout_create(
-						server->lease_seconds,
-						lease_expired_cb,
-						server, NULL);
+	else
+		server->next_expire = l_timeout_create(next_timeout ?: 1,
+							lease_expired_cb,
+							server, NULL);
 }
 
 static void lease_expired_cb(struct l_timeout *timeout, void *user_data)
@@ -239,7 +235,7 @@ static void lease_expired_cb(struct l_timeout *timeout, void *user_data)
 	struct l_dhcp_server *server = user_data;
 	struct l_dhcp_lease *lease = l_queue_peek_tail(server->lease_list);
 
-	if (server->event_handler)
+	if (!lease->offering && server->event_handler)
 		server->event_handler(server, L_DHCP_SERVER_EVENT_LEASE_EXPIRED,
 					server->user_data, lease);
 
@@ -276,17 +272,18 @@ static struct l_dhcp_lease *add_lease(struct l_dhcp_server *server,
 		 */
 		l_queue_insert(server->lease_list, lease,
 					compare_expiry_or_offering, NULL);
-		/*
-		 * This is a new (or renewed lease) so pass NULL for expired so
-		 * the queue's are not modified, only the next_expired timer
-		 */
-		set_next_expire_timer(server, NULL);
 	} else {
 		lease->lifetime = OFFER_TIME;
 		/* Push offered leases to head, active leases after those */
 		l_queue_push_head(server->lease_list, lease);
 	}
 
+	/*
+	 * This is a new (or renewed) lease so pass NULL for expired so the
+	 * queues are not modified, only the next_expire timer.
+	 */
+	set_next_expire_timer(server, NULL);
+
 	SERVER_DEBUG("added lease IP "NIPQUAD_FMT " for "MAC " lifetime=%u",
 			NIPQUAD(yiaddr), MAC_STR(chaddr),
 			server->lease_seconds);
@@ -294,6 +291,17 @@ static struct l_dhcp_lease *add_lease(struct l_dhcp_server *server,
 	return lease;
 }
 
+static bool remove_lease(struct l_dhcp_server *server,
+				struct l_dhcp_lease *lease)
+{
+	if (!l_queue_remove(server->lease_list, lease))
+		return false;
+
+	_dhcp_lease_free(lease);
+	set_next_expire_timer(server, NULL);
+	return true;
+}
+
 static void lease_release(struct l_dhcp_server *server,
 			struct l_dhcp_lease *lease)
 {
-- 
2.30.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] dhcp-server: Add API for manipulating leases
  2021-07-19 14:00 [PATCH 1/2] dhcp-server: Add API for manipulating leases Andrew Zaborowski
  2021-07-19 14:00 ` [PATCH 2/2] dhcp-server: Time out lease offers Andrew Zaborowski
@ 2021-07-22 16:36 ` Denis Kenzior
  1 sibling, 0 replies; 3+ messages in thread
From: Denis Kenzior @ 2021-07-22 16:36 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 905 bytes --]

Hi Andrew,

On 7/19/21 9:00 AM, Andrew Zaborowski wrote:
> Add methods for obtaining and releasing DHCP leases.  There are four
> methods that correspond to the DISCOVER, REQUEST, DECLINE and RELEASE
> messages and two shortcut methods for releasing the leases.  This API is
> useful for implementing mechanisms like the optional P2P IP Allocation
> in the 802.11 4-Way Handshake and FILS IP Address Allocation in 802.11
> Associate frames (both reduces the number of roundtrips in connection
> setup).  Since there are multiple such mechanisms I decided to include
> discover and request as separate methods to allow more flexibility.
> ---
>   ell/dhcp-server.c | 106 +++++++++++++++++++++++++++++++++++++++++++++-
>   ell/dhcp.h        |  15 +++++++
>   ell/ell.sym       |   6 +++
>   3 files changed, 125 insertions(+), 2 deletions(-)
> 

Both applied, thanks.

Regards,
-Denis

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-07-22 16:36 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-19 14:00 [PATCH 1/2] dhcp-server: Add API for manipulating leases Andrew Zaborowski
2021-07-19 14:00 ` [PATCH 2/2] dhcp-server: Time out lease offers Andrew Zaborowski
2021-07-22 16:36 ` [PATCH 1/2] dhcp-server: Add API for manipulating leases Denis Kenzior

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).