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;
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;
}
/**
* 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
* @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;
* 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;
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;
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;