All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tim Kourt <tim.a.kourt@linux.intel.com>
To: ell@lists.01.org
Subject: [PATCH v4] genl: Add unicast handler
Date: Fri, 08 Jul 2016 14:26:03 -0700	[thread overview]
Message-ID: <1468013163-61895-1-git-send-email-tim.a.kourt@linux.intel.com> (raw)

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

---
 ell/genl.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++---------------
 ell/genl.h |  5 ++++
 2 files changed, 80 insertions(+), 24 deletions(-)

diff --git a/ell/genl.c b/ell/genl.c
index 15f4782..85e447a 100644
--- a/ell/genl.c
+++ b/ell/genl.c
@@ -39,6 +39,12 @@
 
 #define MAX_NESTING_LEVEL 4
 
+struct genl_unicast_notify {
+	l_genl_msg_func_t handler;
+	l_genl_destroy_func_t destroy;
+	void *user_data;
+};
+
 struct l_genl {
 	int ref_count;
 	int fd;
@@ -54,6 +60,7 @@ struct l_genl {
 	unsigned int next_notify_id;
 	struct l_queue *family_list;
 	struct l_genl_family *nlctrl;
+	struct genl_unicast_notify *unicast_notify;
 	l_genl_debug_func_t debug_callback;
 	l_genl_destroy_func_t debug_destroy;
 	void *debug_data;
@@ -82,7 +89,7 @@ struct genl_request {
 	void *user_data;
 };
 
-struct genl_notify {
+struct genl_mcast_notify {
 	unsigned int id;
 	uint16_t type;
 	uint32_t group;
@@ -133,7 +140,7 @@ static void destroy_request(void *data)
 
 static void destroy_notify(void *data)
 {
-	struct genl_notify *notify = data;
+	struct genl_mcast_notify *notify = data;
 
 	if (notify->destroy)
 		notify->destroy(notify->user_data);
@@ -356,10 +363,11 @@ static bool match_request_seq(const void *a, const void *b)
 	return request->seq == seq;
 }
 
-static void process_request(struct l_genl *genl, const struct nlmsghdr *nlmsg)
+static void process_unicast(struct l_genl *genl, const struct nlmsghdr *nlmsg)
 {
 	struct l_genl_msg *msg;
 	struct genl_request *request;
+	struct genl_unicast_notify *notify;
 
 	if (nlmsg->nlmsg_type == NLMSG_NOOP ||
 					nlmsg->nlmsg_type == NLMSG_OVERRUN)
@@ -367,28 +375,34 @@ static void process_request(struct l_genl *genl, const struct nlmsghdr *nlmsg)
 
 	request = l_queue_remove_if(genl->pending_list, match_request_seq,
 					L_UINT_TO_PTR(nlmsg->nlmsg_seq));
-	if (!request)
-		return;
 
 	msg = _genl_msg_create(nlmsg);
 	if (!msg) {
-		destroy_request(request);
-		wakeup_writer(genl);
+		if (request) {
+			destroy_request(request);
+			wakeup_writer(genl);
+		}
 		return;
 	}
 
-	if (request->callback && nlmsg->nlmsg_type != NLMSG_DONE)
-		request->callback(msg, request->user_data);
-
-	if (nlmsg->nlmsg_flags & NLM_F_MULTI) {
-		if (nlmsg->nlmsg_type == NLMSG_DONE) {
+	if (request) {
+		if (request->callback && nlmsg->nlmsg_type != NLMSG_DONE)
+			request->callback(msg, request->user_data);
+
+		if (nlmsg->nlmsg_flags & NLM_F_MULTI) {
+			if (nlmsg->nlmsg_type == NLMSG_DONE) {
+				destroy_request(request);
+				wakeup_writer(genl);
+			} else
+				l_queue_push_head(genl->pending_list, request);
+		} else {
 			destroy_request(request);
 			wakeup_writer(genl);
-		} else
-			l_queue_push_head(genl->pending_list, request);
+		}
 	} else {
-		destroy_request(request);
-		wakeup_writer(genl);
+		notify = genl->unicast_notify;
+		if (notify && notify->handler)
+			notify->handler(msg, notify->user_data);
 	}
 
 	l_genl_msg_unref(msg);
@@ -402,7 +416,7 @@ struct notify_type_group {
 
 static void notify_handler(void *data, void *user_data)
 {
-	struct genl_notify *notify = data;
+	struct genl_mcast_notify *notify = data;
 	struct notify_type_group *match = user_data;
 
 	if (notify->type != match->type)
@@ -415,7 +429,7 @@ static void notify_handler(void *data, void *user_data)
 		notify->callback(match->msg, notify->user_data);
 }
 
-static void process_notify(struct l_genl *genl, uint32_t group,
+static void process_multicast(struct l_genl *genl, uint32_t group,
 						const struct nlmsghdr *nlmsg)
 {
 	struct notify_type_group match;
@@ -487,9 +501,9 @@ static bool received_data(struct l_io *io, void *user_data)
 	for (nlmsg = iov.iov_base; NLMSG_OK(nlmsg, bytes_read);
 				nlmsg = NLMSG_NEXT(nlmsg, bytes_read)) {
 		if (group > 0)
-			process_notify(genl, group, nlmsg);
+			process_multicast(genl, group, nlmsg);
 		else
-			process_request(genl, nlmsg);
+			process_unicast(genl, nlmsg);
 	}
 
 	return true;
@@ -607,6 +621,8 @@ LIB_EXPORT void l_genl_unref(struct l_genl *genl)
 	if (genl->debug_destroy)
 		genl->debug_destroy(genl->debug_data);
 
+	l_genl_set_unicast_handler(genl, NULL, NULL, NULL);
+
 	l_free(genl);
 }
 
@@ -638,6 +654,41 @@ LIB_EXPORT bool l_genl_set_close_on_unref(struct l_genl *genl, bool do_close)
 	return true;
 }
 
+LIB_EXPORT bool l_genl_set_unicast_handler(struct l_genl *genl,
+						l_genl_msg_func_t handler,
+						void *user_data,
+						l_genl_destroy_func_t destroy)
+{
+	struct genl_unicast_notify *notify;
+
+	if (!genl)
+		return false;
+
+	notify = genl->unicast_notify;
+	if (notify) {
+		if (notify->destroy)
+			notify->destroy(notify->user_data);
+
+		if (!handler) {
+			l_free(notify);
+			genl->unicast_notify = NULL;
+			return true;
+		}
+	} else {
+		if (!handler)
+			return false;
+
+		notify = l_new(struct genl_unicast_notify, 1);
+		genl->unicast_notify = notify;
+	}
+
+	notify->handler = handler;
+	notify->destroy = destroy;
+	notify->user_data = user_data;
+
+	return true;
+}
+
 const void *_genl_msg_as_bytes(struct l_genl_msg *msg, uint16_t type,
 					uint16_t flags, uint32_t seq,
 					uint32_t pid,
@@ -1265,7 +1316,7 @@ LIB_EXPORT unsigned int l_genl_family_register(struct l_genl_family *family,
 						l_genl_destroy_func_t destroy)
 {
 	struct l_genl *genl;
-	struct genl_notify *notify;
+	struct genl_mcast_notify *notify;
 	struct genl_mcast *mcast;
 
 	if (unlikely(!family) || unlikely(!group))
@@ -1280,7 +1331,7 @@ LIB_EXPORT unsigned int l_genl_family_register(struct l_genl_family *family,
 	if (!mcast)
 		return 0;
 
-	notify = l_new(struct genl_notify, 1);
+	notify = l_new(struct genl_mcast_notify, 1);
 
 	notify->type = family->id;
 	notify->group = mcast->id;
@@ -1303,7 +1354,7 @@ LIB_EXPORT unsigned int l_genl_family_register(struct l_genl_family *family,
 
 static bool match_notify_id(const void *a, const void *b)
 {
-	const struct genl_notify *notify = a;
+	const struct genl_mcast_notify *notify = a;
 	unsigned int id = L_PTR_TO_UINT(b);
 
 	return notify->id == id;
@@ -1313,7 +1364,7 @@ LIB_EXPORT bool l_genl_family_unregister(struct l_genl_family *family,
 							unsigned int id)
 {
 	struct l_genl *genl;
-	struct genl_notify *notify;
+	struct genl_mcast_notify *notify;
 
 	if (!family || !id)
 		return false;
diff --git a/ell/genl.h b/ell/genl.h
index 8f5fd52..5b37d55 100644
--- a/ell/genl.h
+++ b/ell/genl.h
@@ -96,6 +96,11 @@ bool l_genl_family_set_watches(struct l_genl_family *family,
 
 typedef void (*l_genl_msg_func_t)(struct l_genl_msg *msg, void *user_data);
 
+bool l_genl_set_unicast_handler(struct l_genl *genl,
+						l_genl_msg_func_t handler,
+						void *user_data,
+						l_genl_destroy_func_t destroy);
+
 uint32_t l_genl_family_get_version(struct l_genl_family *family);
 
 bool l_genl_family_can_send(struct l_genl_family *family, uint8_t cmd);
-- 
2.5.5


             reply	other threads:[~2016-07-08 21:26 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-08 21:26 Tim Kourt [this message]
2016-07-08 21:35 ` [PATCH v4] genl: Add unicast handler Denis Kenzior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1468013163-61895-1-git-send-email-tim.a.kourt@linux.intel.com \
    --to=tim.a.kourt@linux.intel.com \
    --cc=ell@lists.01.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.