All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] icmp6: Allow multiple event handlers and clean up
@ 2022-01-06 15:05 Andrew Zaborowski
  0 siblings, 0 replies; 2+ messages in thread
From: Andrew Zaborowski @ 2022-01-06 15:05 UTC (permalink / raw)
  To: ell

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

Allow registering multiple event handlers and rename
l_icmp6_client_set_event_handler to l_icmp6_client_add_event_handler
accordingly.  The use case is for a client like IWD to be able to track
routing information.

This also fixes a bug where the destroy callback passed to
l_icmp6_client_set_event_handler wasn't actually used except if
l_icmp6_client_set_event_handler was called again.

While there, add an event_data parameter to the event callback, rename
the "userdata" parameters to "user_data" for consistency and clean up an
extra empty line.
---
 ell/dhcp6.c |  4 ++--
 ell/ell.sym |  2 +-
 ell/icmp6.c | 56 +++++++++++++++++++++++++++++++++++++++--------------
 ell/icmp6.h |  8 ++++----
 4 files changed, 48 insertions(+), 22 deletions(-)

diff --git a/ell/dhcp6.c b/ell/dhcp6.c
index 3e38ff2..40c6f3a 100644
--- a/ell/dhcp6.c
+++ b/ell/dhcp6.c
@@ -1467,7 +1467,7 @@ static void dhcp6_client_send_initial(struct l_dhcp6_client *client)
 
 static void dhcp6_client_icmp6_event(struct l_icmp6_client *icmp6,
 					enum l_icmp6_client_event event,
-					void *user_data)
+					void *event_data, void *user_data)
 {
 	struct l_dhcp6_client *client = user_data;
 
@@ -1521,7 +1521,7 @@ LIB_EXPORT struct l_dhcp6_client *l_dhcp6_client_new(uint32_t ifindex)
 	client->request_na = true;
 
 	client->icmp6 = l_icmp6_client_new(ifindex);
-	l_icmp6_client_set_event_handler(client->icmp6,
+	l_icmp6_client_add_event_handler(client->icmp6,
 						dhcp6_client_icmp6_event,
 						client, NULL);
 
diff --git a/ell/ell.sym b/ell/ell.sym
index 51db458..8da344e 100644
--- a/ell/ell.sym
+++ b/ell/ell.sym
@@ -679,7 +679,7 @@ global:
 	l_icmp6_client_start;
 	l_icmp6_client_stop;
 	l_icmp6_client_get_router;
-	l_icmp6_client_set_event_handler;
+	l_icmp6_client_add_event_handler;
 	l_icmp6_client_set_debug;
 	l_icmp6_client_set_address;
 	l_icmp6_client_set_nodelay;
diff --git a/ell/icmp6.c b/ell/icmp6.c
index 42fe67d..6b1652c 100644
--- a/ell/icmp6.c
+++ b/ell/icmp6.c
@@ -237,6 +237,12 @@ static int icmp6_receive(int s, void *buf, size_t buf_len, struct in6_addr *src)
 	return 0;
 }
 
+struct icmp6_event_handler_entry {
+	l_icmp6_client_event_cb_t handle;
+	void *user_data;
+	l_icmp6_destroy_cb_t destroy;
+};
+
 struct l_icmp6_client {
 	uint32_t ifindex;
 	uint8_t mac[6];
@@ -249,9 +255,7 @@ struct l_icmp6_client {
 	uint32_t route_priority;
 	struct l_queue *routes;
 
-	l_icmp6_client_event_cb_t event_handler;
-	void *event_data;
-	l_icmp6_destroy_cb_t event_destroy;
+	struct l_queue *event_handlers;
 
 	l_icmp6_debug_cb_t debug_handler;
 	l_icmp6_destroy_cb_t debug_destroy;
@@ -262,10 +266,17 @@ struct l_icmp6_client {
 };
 
 static inline void icmp6_client_event_notify(struct l_icmp6_client *client,
-						enum l_icmp6_client_event event)
+						enum l_icmp6_client_event event,
+						void *event_data)
 {
-	if (client->event_handler)
-		client->event_handler(client, event, client->event_data);
+	const struct l_queue_entry *entry;
+
+	for (entry = l_queue_get_entries(client->event_handlers); entry;
+			entry = entry->next) {
+		struct icmp6_event_handler_entry *handler = entry->data;
+
+		handler->handle(client, event, event_data, handler->user_data);
+	}
 }
 
 static bool icmp6_client_remove_route(void *data, void *user_data)
@@ -343,7 +354,8 @@ static int icmp6_client_handle_message(struct l_icmp6_client *client,
 	if (!client->ra) {
 		client->ra = r;
 		icmp6_client_event_notify(client,
-					L_ICMP6_CLIENT_EVENT_ROUTER_FOUND);
+					L_ICMP6_CLIENT_EVENT_ROUTER_FOUND,
+					NULL);
 
 		/* DHCP6 client may have stopped us */
 		if (!client->ra)
@@ -446,6 +458,16 @@ LIB_EXPORT struct l_icmp6_client *l_icmp6_client_new(uint32_t ifindex)
 	return client;
 }
 
+static void icmp6_event_handler_destroy(void *data)
+{
+	struct icmp6_event_handler_entry *handler = data;
+
+	if (handler->destroy)
+		handler->destroy(handler->user_data);
+
+	l_free(handler);
+}
+
 LIB_EXPORT void l_icmp6_client_free(struct l_icmp6_client *client)
 {
 	if (unlikely(!client))
@@ -453,6 +475,7 @@ LIB_EXPORT void l_icmp6_client_free(struct l_icmp6_client *client)
 
 	l_icmp6_client_stop(client);
 	l_queue_destroy(client->routes, NULL);
+	l_queue_destroy(client->event_handlers, icmp6_event_handler_destroy);
 	l_free(client);
 }
 
@@ -537,20 +560,24 @@ LIB_EXPORT const struct l_icmp6_router *l_icmp6_client_get_router(
 	return client->ra;
 }
 
-LIB_EXPORT bool l_icmp6_client_set_event_handler(struct l_icmp6_client *client,
+LIB_EXPORT bool l_icmp6_client_add_event_handler(struct l_icmp6_client *client,
 					l_icmp6_client_event_cb_t handler,
-					void *userdata,
+					void *user_data,
 					l_icmp6_destroy_cb_t destroy)
 {
+	struct icmp6_event_handler_entry *handler_entry;
+
 	if (unlikely(!client))
 		return false;
 
-	if (client->event_destroy)
-		client->event_destroy(client->event_data);
+	if (!client->event_handlers)
+		client->event_handlers = l_queue_new();
 
-	client->event_handler = handler;
-	client->event_data = userdata;
-	client->event_destroy = destroy;
+	handler_entry = l_new(struct icmp6_event_handler_entry, 1);
+	handler_entry->handle = handler;
+	handler_entry->user_data = user_data;
+	handler_entry->destroy = destroy;
+	l_queue_push_head(client->event_handlers, handler_entry);
 
 	return true;
 }
@@ -683,7 +710,6 @@ struct l_icmp6_router *_icmp6_router_parse(const struct nd_router_advert *ra,
 		opts_len -= l;
 	}
 
-
 	r = _icmp6_router_new();
 	memcpy(r->address, src, sizeof(r->address));
 	r->prefixes = l_new(struct route_info, n_prefixes);
diff --git a/ell/icmp6.h b/ell/icmp6.h
index b2231c9..9ce2e24 100644
--- a/ell/icmp6.h
+++ b/ell/icmp6.h
@@ -38,10 +38,10 @@ enum l_icmp6_client_event {
 };
 
 typedef void (*l_icmp6_debug_cb_t)(const char *str, void *user_data);
-typedef void (*l_icmp6_destroy_cb_t)(void *userdata);
+typedef void (*l_icmp6_destroy_cb_t)(void *user_data);
 typedef void (*l_icmp6_client_event_cb_t)(struct l_icmp6_client *client,
 					enum l_icmp6_client_event event,
-					void *userdata);
+					void *event_data, void *user_data);
 
 struct l_icmp6_client *l_icmp6_client_new(uint32_t ifindex);
 void l_icmp6_client_free(struct l_icmp6_client *client);
@@ -51,9 +51,9 @@ bool l_icmp6_client_stop(struct l_icmp6_client *client);
 
 const struct l_icmp6_router *l_icmp6_client_get_router(
 						struct l_icmp6_client *client);
-bool l_icmp6_client_set_event_handler(struct l_icmp6_client *client,
+bool l_icmp6_client_add_event_handler(struct l_icmp6_client *client,
 					l_icmp6_client_event_cb_t handler,
-					void *userdata,
+					void *user_data,
 					l_icmp6_destroy_cb_t destroy);
 bool l_icmp6_client_set_debug(struct l_icmp6_client *client,
 				l_icmp6_debug_cb_t function,
-- 
2.32.0

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

* Re: [PATCH 1/5] icmp6: Allow multiple event handlers and clean up
@ 2022-01-06 18:48 Denis Kenzior
  0 siblings, 0 replies; 2+ messages in thread
From: Denis Kenzior @ 2022-01-06 18:48 UTC (permalink / raw)
  To: ell

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

Hi Andrew,

On 1/6/22 09:05, Andrew Zaborowski wrote:
> Allow registering multiple event handlers and rename
> l_icmp6_client_set_event_handler to l_icmp6_client_add_event_handler
> accordingly.  The use case is for a client like IWD to be able to track
> routing information.
> 
> This also fixes a bug where the destroy callback passed to
> l_icmp6_client_set_event_handler wasn't actually used except if
> l_icmp6_client_set_event_handler was called again.
> 
> While there, add an event_data parameter to the event callback, rename
> the "userdata" parameters to "user_data" for consistency and clean up an
> extra empty line.
> ---
>   ell/dhcp6.c |  4 ++--
>   ell/ell.sym |  2 +-
>   ell/icmp6.c | 56 +++++++++++++++++++++++++++++++++++++++--------------
>   ell/icmp6.h |  8 ++++----
>   4 files changed, 48 insertions(+), 22 deletions(-)
> 

Applied, thanks.

Regards,
-Denis

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

end of thread, other threads:[~2022-01-06 18:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-06 15:05 [PATCH 1/5] icmp6: Allow multiple event handlers and clean up Andrew Zaborowski
2022-01-06 18:48 Denis Kenzior

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.