From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH v2 4/7] Bluetooth: HCI: Always use the identity address when initializing a connection
Date: Tue, 7 Oct 2025 10:49:27 -0400 [thread overview]
Message-ID: <20251007144930.1378274-4-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20251007144930.1378274-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
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>
---
include/net/bluetooth/hci_core.h | 4 +--
net/bluetooth/hci_conn.c | 43 ++++++++++++++++++++------------
net/bluetooth/hci_event.c | 20 +++++++--------
net/bluetooth/hci_sync.c | 2 +-
4 files changed, 40 insertions(+), 29 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2a765a0521b4..c1889e1aa477 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1563,9 +1563,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);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 111f0e37b672..88485b6aeedc 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -911,10 +911,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:
@@ -926,12 +928,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:
@@ -949,7 +953,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;
@@ -1047,7 +1059,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;
@@ -1057,16 +1069,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)
@@ -1398,14 +1410,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;
@@ -1575,7 +1586,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;
@@ -1621,7 +1632,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;
@@ -1632,7 +1644,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;
@@ -1669,7 +1680,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;
}
@@ -1738,7 +1750,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;
@@ -1930,7 +1942,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;
@@ -2121,12 +2133,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);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index f1735a7e48a7..ba0a7b41611f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -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));
@@ -5660,14 +5661,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
@@ -5949,7 +5949,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))
@@ -6482,7 +6482,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))
@@ -6923,7 +6923,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);
@@ -7040,7 +7040,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;
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 571e07f81523..b5e58cbf0d46 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -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))
--
2.51.0
next prev parent reply other threads:[~2025-10-07 14:49 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-07 14:49 [PATCH v2 1/7] Bluetooth: HCI: Add initial support for PAST Luiz Augusto von Dentz
2025-10-07 14:49 ` [PATCH v2 2/7] Bluetooth: hci_core: Introduce HCI_CONN_FLAG_PAST Luiz Augusto von Dentz
2025-10-07 14:49 ` [PATCH v2 3/7] Bluetooth: ISO: Add support to bind to trigger PAST Luiz Augusto von Dentz
2025-10-07 16:16 ` Pauli Virtanen
2025-10-07 17:50 ` Luiz Augusto von Dentz
2025-10-07 14:49 ` Luiz Augusto von Dentz [this message]
2025-10-07 14:49 ` [PATCH v2 5/7] Bluetooth: ISO: Attempt to resolve broadcast address Luiz Augusto von Dentz
2025-10-07 14:49 ` [PATCH v2 6/7] Bluetooth: MGMT: Allow use of Set Device Flags without Add Device Luiz Augusto von Dentz
2025-10-07 14:49 ` [PATCH v2 7/7] Bluetooth: ISO: Fix not updating BIS sender source address Luiz Augusto von Dentz
2025-10-07 15:36 ` [v2,1/7] Bluetooth: HCI: Add initial support for PAST bluez.test.bot
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=20251007144930.1378274-4-luiz.dentz@gmail.com \
--to=luiz.dentz@gmail.com \
--cc=linux-bluetooth@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox