match: add name matching, match kernel notifications
authorKay Sievers <kay@vrfy.org>
Thu, 19 Dec 2013 05:39:50 +0000 (06:39 +0100)
committerKay Sievers <kay@vrfy.org>
Thu, 19 Dec 2013 05:48:43 +0000 (06:48 +0100)
match.c
message.h
notify.c

diff --git a/match.c b/match.c
index 546617a3081080ab0dfc2f1174ffa54609b543d5..aa7aee254c0eef8e29cc24bd5d394b0bd32e113b 100644 (file)
--- a/match.c
+++ b/match.c
@@ -232,7 +232,7 @@ static
 bool kdbus_match_db_match_from_kernel(struct kdbus_match_db *db,
                                      struct kdbus_kmsg *kmsg)
 {
-       u64 type = kmsg->notification_type;
+       u64 msg_type = kmsg->notify_type;
        struct kdbus_match_db_entry *e;
        bool matched = false;
 
@@ -241,41 +241,58 @@ bool kdbus_match_db_match_from_kernel(struct kdbus_match_db *db,
                struct kdbus_match_db_entry_item *ei;
 
                list_for_each_entry(ei, &e->items_list, list_entry) {
-                       if (ei->id == 0 ||
-                           ei->id == KDBUS_MATCH_SRC_ID_ANY ||
-                           ei->id == e->src_id) {
-
-                               if (ei->type == KDBUS_MATCH_ID_ADD &&
-                                   type == KDBUS_ITEM_ID_ADD) {
-                                       matched = true;
-                                       break;
-                               }
-
-                               if (ei->type == KDBUS_MATCH_ID_REMOVE &&
-                                   type == KDBUS_ITEM_ID_REMOVE) {
-                                       matched = true;
-                                       break;
-                               }
-                       }
-
-                       if (e->src_id != KDBUS_MATCH_SRC_ID_ANY &&
-                           e->src_id != 0)
+                       /* the kernel has no source connection */
+                       if (e->src_id > 0)
                                continue;
 
-                       if (ei->type == KDBUS_MATCH_NAME_ADD &&
-                           type == KDBUS_ITEM_NAME_ADD) {
-                               matched = true;
+                       /* match entry against type of message */
+                       switch(ei->type) {
+                       case KDBUS_MATCH_ID_ADD:
+                               if (msg_type != KDBUS_ITEM_ID_ADD)
+                                       continue;
+                               break;
+
+                       case KDBUS_MATCH_ID_REMOVE:
+                               if (msg_type != KDBUS_ITEM_ID_REMOVE)
+                                       continue;
+                               break;
+
+                       case KDBUS_MATCH_NAME_ADD:
+                               if (msg_type != KDBUS_ITEM_NAME_ADD)
+                                       continue;
                                break;
+
+                       case KDBUS_MATCH_NAME_CHANGE:
+                               if (msg_type != KDBUS_ITEM_NAME_CHANGE)
+                                       continue;
+                               break;
+
+                       case KDBUS_MATCH_NAME_REMOVE:
+                               if (msg_type != KDBUS_ITEM_NAME_REMOVE)
+                                       continue;
+                               break;
+
+                       default:
+                               BUG_ON(1);
                        }
 
-                       if (ei->type == KDBUS_MATCH_NAME_CHANGE &&
-                           type == KDBUS_ITEM_NAME_CHANGE) {
+                       /* the types match, now check the value */
+                       switch(ei->type) {
+                       case KDBUS_MATCH_ID_ADD:
+                       case KDBUS_MATCH_ID_REMOVE:
+                               if (ei->id > 0 && ei->id != kmsg->notify_id)
+                                       continue;
+
                                matched = true;
                                break;
-                       }
 
-                       if (ei->type == KDBUS_MATCH_NAME_REMOVE &&
-                           type == KDBUS_ITEM_NAME_REMOVE) {
+                       case KDBUS_MATCH_NAME_ADD:
+                       case KDBUS_MATCH_NAME_CHANGE:
+                       case KDBUS_MATCH_NAME_REMOVE:
+                               if (ei->name &&
+                                   strcmp(ei->name, kmsg->notify_name) != 0)
+                                       continue;
+
                                matched = true;
                                break;
                        }
index ed5e349c0c103a7f042cae0a33a1527135a9b8fc..925283274b59ff9bef661fe677b5b1cef2a09204 100644 (file)
--- a/message.h
+++ b/message.h
@@ -18,7 +18,9 @@
 
 /**
  * struct kdbus_kmsg - internal message handling data
- * @notification_type: Short-cut for faster lookup
+ * @notify_type:       Short-cut for faster lookup
+ * @notify_id:         Short-cut for faster lookup
+ * @notify_name:       Short-cut for faster lookup
  * @dst_name:          Short-cut to msg for faster lookup
  * @bloom:             Short-cut to msg for faster lookup
  * @bloom_size:                Short-cut to msg for faster lookup
@@ -32,7 +34,9 @@
  * @msg:               Message from or to userspace
  */
 struct kdbus_kmsg {
-       u64 notification_type;
+       u64 notify_type;
+       u64 notify_id;
+       const char *notify_name;
        const char *dst_name;
        const u64 *bloom;
        unsigned int bloom_size;
index bccfa5e37602463ba13e1ae0d0fc9af64ab9f6cd..f1cf412103af2900e08c490c79fe33ed441df81e 100644 (file)
--- a/notify.c
+++ b/notify.c
@@ -38,7 +38,7 @@ static int kdbus_notify_reply(u64 id, u64 cookie, u64 msg_type,
         * struct kdbus_item, so make a shortcut here for
         * faster lookup in the match db.
         */
-       kmsg->notification_type = msg_type;
+       kmsg->notify_type = msg_type;
        kmsg->msg.dst_id = id;
        kmsg->msg.src_id = KDBUS_SRC_ID_KERNEL;
        kmsg->msg.payload_type = KDBUS_PAYLOAD_KERNEL;
@@ -127,13 +127,14 @@ int kdbus_notify_name_change(u64 type,
 
        kmsg->msg.dst_id = KDBUS_DST_ID_BROADCAST;
        kmsg->msg.src_id = KDBUS_SRC_ID_KERNEL;
-       kmsg->notification_type = type;
+       kmsg->notify_type = type;
        kmsg->msg.items[0].type = type;
        kmsg->msg.items[0].name_change.old.id = old_id;
        kmsg->msg.items[0].name_change.old.flags = old_flags;
        kmsg->msg.items[0].name_change.new.id = new_id;
        kmsg->msg.items[0].name_change.new.flags = new_flags;
        memcpy(kmsg->msg.items[0].name_change.name, name, name_len);
+       kmsg->notify_name = kmsg->msg.items[0].name_change.name;
 
        list_add_tail(&kmsg->queue_entry, queue_list);
        return ret;
@@ -164,7 +165,8 @@ int kdbus_notify_id_change(u64 type, u64 id, u64 flags,
 
        kmsg->msg.dst_id = KDBUS_DST_ID_BROADCAST;
        kmsg->msg.src_id = KDBUS_SRC_ID_KERNEL;
-       kmsg->notification_type = type;
+       kmsg->notify_type = type;
+       kmsg->notify_id = id;
        kmsg->msg.items[0].type = type;
        kmsg->msg.items[0].id_change.id = id;
        kmsg->msg.items[0].id_change.flags = flags;