mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Bluetooth: HCI: Always use the identity address when initializing a connection
This makes sure hci_conn is initialized with the identity address if a matching IRK exists which avoids the trouble of having to do it at multiple places which seems to be missing (e.g. CIS, BIS and PA). Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
@@ -1571,9 +1571,9 @@ int hci_le_create_cis_pending(struct hci_dev *hdev);
|
||||
int hci_conn_check_create_cis(struct hci_conn *conn);
|
||||
|
||||
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||
u8 role, u16 handle);
|
||||
u8 dst_type, u8 role, u16 handle);
|
||||
struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
|
||||
bdaddr_t *dst, u8 role);
|
||||
bdaddr_t *dst, u8 dst_type, u8 role);
|
||||
void hci_conn_del(struct hci_conn *conn);
|
||||
void hci_conn_hash_flush(struct hci_dev *hdev);
|
||||
|
||||
|
||||
@@ -922,10 +922,12 @@ static int hci_conn_hash_alloc_unset(struct hci_dev *hdev)
|
||||
U16_MAX, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||
static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type,
|
||||
bdaddr_t *dst, u8 dst_type,
|
||||
u8 role, u16 handle)
|
||||
{
|
||||
struct hci_conn *conn;
|
||||
struct smp_irk *irk = NULL;
|
||||
|
||||
switch (type) {
|
||||
case ACL_LINK:
|
||||
@@ -937,12 +939,14 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
|
||||
case PA_LINK:
|
||||
if (!hdev->iso_mtu)
|
||||
return ERR_PTR(-ECONNREFUSED);
|
||||
irk = hci_get_irk(hdev, dst, dst_type);
|
||||
break;
|
||||
case LE_LINK:
|
||||
if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
|
||||
return ERR_PTR(-ECONNREFUSED);
|
||||
if (!hdev->le_mtu && hdev->acl_mtu < HCI_MIN_LE_MTU)
|
||||
return ERR_PTR(-ECONNREFUSED);
|
||||
irk = hci_get_irk(hdev, dst, dst_type);
|
||||
break;
|
||||
case SCO_LINK:
|
||||
case ESCO_LINK:
|
||||
@@ -960,7 +964,15 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
|
||||
if (!conn)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
bacpy(&conn->dst, dst);
|
||||
/* If and IRK exists use its identity address */
|
||||
if (!irk) {
|
||||
bacpy(&conn->dst, dst);
|
||||
conn->dst_type = dst_type;
|
||||
} else {
|
||||
bacpy(&conn->dst, &irk->bdaddr);
|
||||
conn->dst_type = irk->addr_type;
|
||||
}
|
||||
|
||||
bacpy(&conn->src, &hdev->bdaddr);
|
||||
conn->handle = handle;
|
||||
conn->hdev = hdev;
|
||||
@@ -1059,7 +1071,7 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
|
||||
}
|
||||
|
||||
struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
|
||||
bdaddr_t *dst, u8 role)
|
||||
bdaddr_t *dst, u8 dst_type, u8 role)
|
||||
{
|
||||
int handle;
|
||||
|
||||
@@ -1069,16 +1081,16 @@ struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
|
||||
if (unlikely(handle < 0))
|
||||
return ERR_PTR(-ECONNREFUSED);
|
||||
|
||||
return __hci_conn_add(hdev, type, dst, role, handle);
|
||||
return __hci_conn_add(hdev, type, dst, dst_type, role, handle);
|
||||
}
|
||||
|
||||
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||
u8 role, u16 handle)
|
||||
u8 dst_type, u8 role, u16 handle)
|
||||
{
|
||||
if (handle > HCI_CONN_HANDLE_MAX)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
return __hci_conn_add(hdev, type, dst, role, handle);
|
||||
return __hci_conn_add(hdev, type, dst, dst_type, role, handle);
|
||||
}
|
||||
|
||||
static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason)
|
||||
@@ -1410,14 +1422,13 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
if (conn) {
|
||||
bacpy(&conn->dst, dst);
|
||||
} else {
|
||||
conn = hci_conn_add_unset(hdev, LE_LINK, dst, role);
|
||||
conn = hci_conn_add_unset(hdev, LE_LINK, dst, dst_type, role);
|
||||
if (IS_ERR(conn))
|
||||
return conn;
|
||||
hci_conn_hold(conn);
|
||||
conn->pending_sec_level = sec_level;
|
||||
}
|
||||
|
||||
conn->dst_type = dst_type;
|
||||
conn->sec_level = BT_SECURITY_LOW;
|
||||
conn->conn_timeout = conn_timeout;
|
||||
conn->le_adv_phy = phy;
|
||||
@@ -1587,7 +1598,7 @@ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
memcmp(conn->le_per_adv_data, base, base_len)))
|
||||
return ERR_PTR(-EADDRINUSE);
|
||||
|
||||
conn = hci_conn_add_unset(hdev, BIS_LINK, dst, HCI_ROLE_MASTER);
|
||||
conn = hci_conn_add_unset(hdev, BIS_LINK, dst, 0, HCI_ROLE_MASTER);
|
||||
if (IS_ERR(conn))
|
||||
return conn;
|
||||
|
||||
@@ -1633,7 +1644,8 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
|
||||
BT_DBG("requesting refresh of dst_addr");
|
||||
|
||||
conn = hci_conn_add_unset(hdev, LE_LINK, dst, HCI_ROLE_MASTER);
|
||||
conn = hci_conn_add_unset(hdev, LE_LINK, dst, dst_type,
|
||||
HCI_ROLE_MASTER);
|
||||
if (IS_ERR(conn))
|
||||
return conn;
|
||||
|
||||
@@ -1644,7 +1656,6 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
|
||||
conn->state = BT_CONNECT;
|
||||
set_bit(HCI_CONN_SCANNING, &conn->flags);
|
||||
conn->dst_type = dst_type;
|
||||
conn->sec_level = BT_SECURITY_LOW;
|
||||
conn->pending_sec_level = sec_level;
|
||||
conn->conn_timeout = conn_timeout;
|
||||
@@ -1681,7 +1692,8 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
|
||||
acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
|
||||
if (!acl) {
|
||||
acl = hci_conn_add_unset(hdev, ACL_LINK, dst, HCI_ROLE_MASTER);
|
||||
acl = hci_conn_add_unset(hdev, ACL_LINK, dst, 0,
|
||||
HCI_ROLE_MASTER);
|
||||
if (IS_ERR(acl))
|
||||
return acl;
|
||||
}
|
||||
@@ -1750,7 +1762,7 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||
|
||||
sco = hci_conn_hash_lookup_ba(hdev, type, dst);
|
||||
if (!sco) {
|
||||
sco = hci_conn_add_unset(hdev, type, dst, HCI_ROLE_MASTER);
|
||||
sco = hci_conn_add_unset(hdev, type, dst, 0, HCI_ROLE_MASTER);
|
||||
if (IS_ERR(sco)) {
|
||||
hci_conn_drop(acl);
|
||||
return sco;
|
||||
@@ -1942,7 +1954,7 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
cis = hci_conn_hash_lookup_cis(hdev, dst, dst_type, qos->ucast.cig,
|
||||
qos->ucast.cis);
|
||||
if (!cis) {
|
||||
cis = hci_conn_add_unset(hdev, CIS_LINK, dst,
|
||||
cis = hci_conn_add_unset(hdev, CIS_LINK, dst, dst_type,
|
||||
HCI_ROLE_MASTER);
|
||||
if (IS_ERR(cis))
|
||||
return cis;
|
||||
@@ -2133,12 +2145,11 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
|
||||
bt_dev_dbg(hdev, "dst %pMR type %d sid %d", dst, dst_type, sid);
|
||||
|
||||
conn = hci_conn_add_unset(hdev, PA_LINK, dst, HCI_ROLE_SLAVE);
|
||||
conn = hci_conn_add_unset(hdev, PA_LINK, dst, dst_type, HCI_ROLE_SLAVE);
|
||||
if (IS_ERR(conn))
|
||||
return conn;
|
||||
|
||||
conn->iso_qos = *qos;
|
||||
conn->dst_type = dst_type;
|
||||
conn->sid = sid;
|
||||
conn->state = BT_LISTEN;
|
||||
conn->conn_timeout = msecs_to_jiffies(qos->bcast.sync_timeout * 10);
|
||||
|
||||
@@ -2267,7 +2267,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
|
||||
} else {
|
||||
if (!conn) {
|
||||
conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr,
|
||||
HCI_ROLE_MASTER);
|
||||
0, HCI_ROLE_MASTER);
|
||||
if (IS_ERR(conn))
|
||||
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
||||
}
|
||||
@@ -3123,7 +3123,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
|
||||
&ev->bdaddr,
|
||||
BDADDR_BREDR)) {
|
||||
conn = hci_conn_add_unset(hdev, ev->link_type,
|
||||
&ev->bdaddr, HCI_ROLE_SLAVE);
|
||||
&ev->bdaddr, 0,
|
||||
HCI_ROLE_SLAVE);
|
||||
if (IS_ERR(conn)) {
|
||||
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
||||
goto unlock;
|
||||
@@ -3299,7 +3300,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
|
||||
&ev->bdaddr);
|
||||
if (!conn) {
|
||||
conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr,
|
||||
conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr, 0,
|
||||
HCI_ROLE_SLAVE);
|
||||
if (IS_ERR(conn)) {
|
||||
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
||||
@@ -5670,14 +5671,13 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
|
||||
if (status)
|
||||
goto unlock;
|
||||
|
||||
conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, role);
|
||||
conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, bdaddr_type,
|
||||
role);
|
||||
if (IS_ERR(conn)) {
|
||||
bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
conn->dst_type = bdaddr_type;
|
||||
|
||||
/* If we didn't have a hci_conn object previously
|
||||
* but we're in central role this must be something
|
||||
* initiated using an accept list. Since accept list based
|
||||
@@ -5982,7 +5982,7 @@ static void hci_le_past_received_evt(struct hci_dev *hdev, void *data,
|
||||
goto unlock;
|
||||
|
||||
/* Add connection to indicate PA sync event */
|
||||
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY,
|
||||
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY, 0,
|
||||
HCI_ROLE_SLAVE);
|
||||
|
||||
if (IS_ERR(pa_sync))
|
||||
@@ -6515,7 +6515,7 @@ static void hci_le_pa_sync_established_evt(struct hci_dev *hdev, void *data,
|
||||
goto unlock;
|
||||
|
||||
/* Add connection to indicate PA sync event */
|
||||
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY,
|
||||
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY, 0,
|
||||
HCI_ROLE_SLAVE);
|
||||
|
||||
if (IS_ERR(pa_sync))
|
||||
@@ -6956,7 +6956,7 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data,
|
||||
|
||||
cis = hci_conn_hash_lookup_handle(hdev, cis_handle);
|
||||
if (!cis) {
|
||||
cis = hci_conn_add(hdev, CIS_LINK, &acl->dst,
|
||||
cis = hci_conn_add(hdev, CIS_LINK, &acl->dst, acl->dst_type,
|
||||
HCI_ROLE_SLAVE, cis_handle);
|
||||
if (IS_ERR(cis)) {
|
||||
hci_le_reject_cis(hdev, ev->cis_handle);
|
||||
@@ -7073,7 +7073,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
|
||||
bt_dev_dbg(hdev, "ignore too large handle %u", handle);
|
||||
continue;
|
||||
}
|
||||
bis = hci_conn_add(hdev, BIS_LINK, BDADDR_ANY,
|
||||
bis = hci_conn_add(hdev, BIS_LINK, BDADDR_ANY, 0,
|
||||
HCI_ROLE_SLAVE, handle);
|
||||
if (IS_ERR(bis))
|
||||
continue;
|
||||
|
||||
@@ -7013,7 +7013,7 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
|
||||
goto unlock;
|
||||
|
||||
/* Add connection to indicate PA sync error */
|
||||
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY,
|
||||
pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY, 0,
|
||||
HCI_ROLE_SLAVE);
|
||||
|
||||
if (IS_ERR(pa_sync))
|
||||
|
||||
Reference in New Issue
Block a user