OSDN Git Service

Bluetooth: Add bdaddr_list_with_flags for classic whitelist
authorAbhishek Pandit-Subedi <abhishekpandit@chromium.org>
Wed, 17 Jun 2020 14:39:08 +0000 (16:39 +0200)
committerJohan Hedberg <johan.hedberg@intel.com>
Thu, 18 Jun 2020 10:11:07 +0000 (13:11 +0300)
In order to more easily add device flags to classic devices, create
a new type of bdaddr_list that supports setting flags.

Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Reviewed-by: Alain Michaud <alainm@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c

index 0d5dbb6..95a3935 100644 (file)
@@ -136,6 +136,13 @@ struct bdaddr_list_with_irk {
        u8 local_irk[16];
 };
 
+struct bdaddr_list_with_flags {
+       struct list_head list;
+       bdaddr_t bdaddr;
+       u8 bdaddr_type;
+       u32 current_flags;
+};
+
 struct bt_uuid {
        struct list_head list;
        u8 uuid[16];
@@ -1169,12 +1176,19 @@ struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
 struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
                                    struct list_head *list, bdaddr_t *bdaddr,
                                    u8 type);
+struct bdaddr_list_with_flags *
+hci_bdaddr_list_lookup_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+                                 u8 type);
 int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type);
 int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
-                                       u8 type, u8 *peer_irk, u8 *local_irk);
+                                u8 type, u8 *peer_irk, u8 *local_irk);
+int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+                                  u8 type, u32 flags);
 int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type);
 int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
-                                                               u8 type);
+                                u8 type);
+int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+                                  u8 type);
 void hci_bdaddr_list_clear(struct list_head *list);
 
 struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
index 4f1052a..8a471be 100644 (file)
@@ -3023,6 +3023,20 @@ struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
        return NULL;
 }
 
+struct bdaddr_list_with_flags *
+hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
+                                 bdaddr_t *bdaddr, u8 type)
+{
+       struct bdaddr_list_with_flags *b;
+
+       list_for_each_entry(b, bdaddr_list, list) {
+               if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
+                       return b;
+       }
+
+       return NULL;
+}
+
 void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
 {
        struct bdaddr_list *b, *n;
@@ -3084,6 +3098,30 @@ int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
        return 0;
 }
 
+int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+                                  u8 type, u32 flags)
+{
+       struct bdaddr_list_with_flags *entry;
+
+       if (!bacmp(bdaddr, BDADDR_ANY))
+               return -EBADF;
+
+       if (hci_bdaddr_list_lookup(list, bdaddr, type))
+               return -EEXIST;
+
+       entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+       if (!entry)
+               return -ENOMEM;
+
+       bacpy(&entry->bdaddr, bdaddr);
+       entry->bdaddr_type = type;
+       entry->current_flags = flags;
+
+       list_add(&entry->list, list);
+
+       return 0;
+}
+
 int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
 {
        struct bdaddr_list *entry;
@@ -3123,6 +3161,26 @@ int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
        return 0;
 }
 
+int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+                                  u8 type)
+{
+       struct bdaddr_list_with_flags *entry;
+
+       if (!bacmp(bdaddr, BDADDR_ANY)) {
+               hci_bdaddr_list_clear(list);
+               return 0;
+       }
+
+       entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
+       if (!entry)
+               return -ENOENT;
+
+       list_del(&entry->list);
+       kfree(entry);
+
+       return 0;
+}
+
 /* This function requires the caller holds hdev->lock */
 struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
                                               bdaddr_t *addr, u8 addr_type)
index cfeaee3..8981954 100644 (file)
@@ -2697,10 +2697,10 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
         */
        if (hci_dev_test_flag(hdev, HCI_MGMT) &&
            !hci_dev_test_flag(hdev, HCI_CONNECTABLE) &&
-           !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr,
-                                   BDADDR_BREDR)) {
-                   hci_reject_conn(hdev, &ev->bdaddr);
-                   return;
+           !hci_bdaddr_list_lookup_with_flags(&hdev->whitelist, &ev->bdaddr,
+                                              BDADDR_BREDR)) {
+               hci_reject_conn(hdev, &ev->bdaddr);
+               return;
        }
 
        /* Connection accepted */
index ecfdfc4..d0d0fa8 100644 (file)
@@ -6000,8 +6000,9 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
                        goto unlock;
                }
 
-               err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr,
-                                         cp->addr.type);
+               err = hci_bdaddr_list_add_with_flags(&hdev->whitelist,
+                                                    &cp->addr.bdaddr,
+                                                    cp->addr.type, 0);
                if (err)
                        goto unlock;