* [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve
2026-09-07 23:20 [PATCH 0/2] Bluetooth: dial the peer's on-air address when we cannot resolve Radek Podgorny
2026-09-07 23:20 ` [PATCH 1/2] Bluetooth: record when an IRK's RPA was last seen Radek Podgorny
@ 2026-09-07 23:20 ` Radek Podgorny
2026-09-08 0:03 ` Bluetooth: dial the peer's on-air address " bluez.test.bot
` (2 more replies)
1 sibling, 3 replies; 9+ messages in thread
From: Radek Podgorny @ 2026-09-07 23:20 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz
Cc: linux-bluetooth, linux-kernel, Radek Podgorny
An identity address only reaches a peer that is advertising an RPA if the
controller resolves on our behalf. Where it cannot, the host has to put the
peer's on-air address on air itself.
hci_connect_le() used to do exactly that, swapping the caller's identity
address for the peer's cached RPA before creating the connection:
irk = hci_find_irk_by_addr(hdev, dst, dst_type);
if (irk && bacmp(&irk->rpa, BDADDR_ANY)) {
dst = &irk->rpa;
dst_type = ADDR_LE_DEV_RANDOM;
}
__hci_conn_add() now resolves that RPA back to the identity address when it
stores it, so the swap no longer survives into conn->dst and the identity
address is what goes out. Storing the identity is right for host
bookkeeping, but nothing translates it again on the way to the controller.
A peer advertising an RPA cannot answer an identity address, so the attempt
burns a full create-connection timeout. That is not merely a slow connect:
a controller without extended scanning cannot scan while it is initiating,
so every dead attempt also takes the scanner off the air for the whole
timeout.
Measured on a CYW43438, which reports neither LL Privacy nor extended
advertising (LE features 3f 00 00 08 00 00 00 00), against a peer
advertising a resolvable private address the host holds the IRK for, with
the connection requested on the peer's identity address:
before: LE Create Connection to the identity address, public type
1.61s -> 22.07s, then LE Create Connection Cancel
LE Connection Complete: Unknown Connection Identifier (0x02)
after: LE Create Connection to the peer's RPA, random type
LE Connection Complete: Success
Advertising reports reaching the host per second, same window, same five
unrelated devices on the adapter:
before 1s:2 [nothing from 2s through 21s] 22s:5 23s:3
after 0s:11 1s:5 2s:2 3s:5 4s:3 5s:4 ... 21s:2 22s:1 23s:2
One dead connect costs twenty seconds of scanning for every device on the
adapter, not just the one being dialled. Enough of them in a row and the
host's advertisement monitor sees nothing for long enough to power-cycle
the adapter, dropping every link on it.
Choose the address to dial rather than assuming conn->dst:
- if the controller is resolving and this peer's IRK is programmed, the
identity address is correct and the resolving list translates it.
Testing ll_privacy_capable() alone is not enough: it reports the
feature bit, not whether resolution is switched on and not whether this
peer is in the list. Resolution is cleared with the other volatile
flags on power-off and switched off again while suspend pauses
scanning, and a peer's IRK is only programmed along the accept list
path, so a direct-connect target, a peer without
HCI_CONN_FLAG_ADDRESS_RESOLUTION, and one that did not fit in a full
list are all absent from it;
- a dst that is already a private address is what the peer is on air with
and needs no translation;
- otherwise use the last RPA resolved for this peer, while it is still
fresh. A stale RPA is worse than none: the peer has already rotated
away from it.
The first branch was measured on an Intel controller that does report LL
Privacy. With the peer's IRK programmed into the controller's resolving
list the host puts the identity address on air and the controller
translates it, reporting Resolved Public with the peer's RPA
6D:CA:DB:24:14:E9 in LE Enhanced Connection Complete. With the peer
absent from the list the same setup dials that RPA itself.
The address is chosen once in hci_le_create_conn_sync() and handed to
whichever command builder runs, the same way own_addr_type already is, so
the two paths cannot disagree.
Store the chosen address in conn->dst when it is not already there. The
connection complete event names the address that was dialled and
hci_conn_hash_lookup_role() finds a connection by conn->dst, so leaving the
identity address behind would make the event miss this connection and add a
second one while this one waits out its timeout. le_conn_complete_evt()
resolves the address back to the identity once the link is up, which is the
same round trip hci_connect_le() has always relied on.
Fixes: 14b06c3a88f7 ("Bluetooth: HCI: Always use the identity address when initializing a connection")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Radek Podgorny <radek@podgorny.cz>
---
net/bluetooth/hci_sync.c | 82 ++++++++++++++++++++++++++++++++++++----
1 file changed, 75 insertions(+), 7 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 5376ade2cdc1..136d801baa85 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -6794,8 +6794,60 @@ static void set_ext_conn_params(struct hci_conn *conn,
p->max_ce_len = cpu_to_le16(0x0000);
}
+/* An RPA resolved more recently than this is taken to still be what the peer
+ * is on air with. The spec-recommended rotation period is the best estimate
+ * the host has; a stale RPA costs one failed connect, while falling back to an
+ * identity address the controller cannot translate costs a full
+ * create-connection timeout that cannot succeed.
+ */
+#define HCI_RPA_FRESH_TIMEOUT secs_to_jiffies(HCI_DEFAULT_RPA_TIMEOUT)
+
+/* Pick the address to put on air for an outgoing LE connection.
+ *
+ * hci_conn_add() stores the peer identity address whenever an IRK resolves,
+ * which is what host bookkeeping wants but not what reaches the peer: an
+ * identity address only gets there if the controller resolves on our behalf.
+ * Prefer an address the peer has actually been seen using.
+ *
+ * This function requires the caller holds hdev->lock.
+ */
+static void hci_conn_select_peer_addr(struct hci_dev *hdev,
+ struct hci_conn *conn,
+ bdaddr_t *peer_addr, u8 *peer_addr_type)
+{
+ struct smp_irk *irk;
+
+ /* conn->dst is right both when the controller translates it for us and
+ * when it is already a private address.
+ */
+ bacpy(peer_addr, &conn->dst);
+ *peer_addr_type = conn->dst_type;
+
+ /* Supporting LL Privacy is not enough: resolution has to be switched on
+ * and this peer's IRK actually programmed, which only happens along the
+ * accept list path.
+ */
+ if (hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION) &&
+ hci_bdaddr_list_lookup_with_irk(&hdev->le_resolv_list, &conn->dst,
+ conn->dst_type))
+ return;
+
+ if (hci_bdaddr_is_rpa(&conn->dst, conn->dst_type))
+ return;
+
+ irk = hci_find_irk_by_addr(hdev, &conn->dst, conn->dst_type);
+ if (!irk || !bacmp(&irk->rpa, BDADDR_ANY) ||
+ !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
+ HCI_RPA_FRESH_TIMEOUT))
+ return;
+
+ bacpy(peer_addr, &irk->rpa);
+ *peer_addr_type = ADDR_LE_DEV_RANDOM;
+}
+
static int hci_le_ext_create_conn_sync(struct hci_dev *hdev,
- struct hci_conn *conn, u8 own_addr_type)
+ struct hci_conn *conn, u8 own_addr_type,
+ bdaddr_t *peer_addr, u8 peer_addr_type)
{
struct hci_cp_le_ext_create_conn *cp;
struct hci_cp_le_ext_conn_param *p;
@@ -6807,8 +6859,8 @@ static int hci_le_ext_create_conn_sync(struct hci_dev *hdev,
memset(cp, 0, sizeof(*cp));
- bacpy(&cp->peer_addr, &conn->dst);
- cp->peer_addr_type = conn->dst_type;
+ bacpy(&cp->peer_addr, peer_addr);
+ cp->peer_addr_type = peer_addr_type;
cp->own_addr_type = own_addr_type;
plen = sizeof(*cp);
@@ -6849,7 +6901,8 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
{
struct hci_cp_le_create_conn cp;
struct hci_conn_params *params;
- u8 own_addr_type;
+ u8 own_addr_type, peer_addr_type;
+ bdaddr_t peer_addr;
int err;
struct hci_conn *conn = data;
@@ -6927,9 +6980,24 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
*/
set_bit(HCI_CONN_CREATE, &conn->flags);
+ hci_dev_lock(hdev);
+ hci_conn_select_peer_addr(hdev, conn, &peer_addr, &peer_addr_type);
+
+ /* The connection complete event names the address that was dialled and
+ * hci_conn_hash_lookup_role() finds a connection by conn->dst, so
+ * leaving the identity address there would make the event miss this
+ * connection and build a second one. Follow the dialled address
+ * instead; le_conn_complete_evt() resolves it back once the link is
+ * up.
+ */
+ bacpy(&conn->dst, &peer_addr);
+ conn->dst_type = peer_addr_type;
+ hci_dev_unlock(hdev);
+
/* Send command LE Extended Create Connection if supported */
if (use_ext_conn(hdev)) {
- err = hci_le_ext_create_conn_sync(hdev, conn, own_addr_type);
+ err = hci_le_ext_create_conn_sync(hdev, conn, own_addr_type,
+ &peer_addr, peer_addr_type);
goto done;
}
@@ -6938,8 +7006,8 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
cp.scan_interval = cpu_to_le16(hdev->le_scan_int_connect);
cp.scan_window = cpu_to_le16(hdev->le_scan_window_connect);
- bacpy(&cp.peer_addr, &conn->dst);
- cp.peer_addr_type = conn->dst_type;
+ bacpy(&cp.peer_addr, &peer_addr);
+ cp.peer_addr_type = peer_addr_type;
cp.own_address_type = own_addr_type;
cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 1/2] Bluetooth: record when an IRK's RPA was last seen
2026-09-07 23:20 [PATCH 0/2] Bluetooth: dial the peer's on-air address when we cannot resolve Radek Podgorny
@ 2026-09-07 23:20 ` Radek Podgorny
2026-09-07 23:20 ` [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve Radek Podgorny
1 sibling, 0 replies; 9+ messages in thread
From: Radek Podgorny @ 2026-09-07 23:20 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz
Cc: linux-bluetooth, linux-kernel, Radek Podgorny
hci_find_irk_by_rpa() caches the resolvable private address it just
matched in irk->rpa, but nothing records when. A cached RPA is only
useful while the peer is still using it -- RPAs rotate on the order of
15 minutes -- and without a timestamp there is no way to tell a value
seen seconds ago from one left over from hours ago.
Stamp the time in both loops, the cache hit as well as the resolve, so
the stamp tracks when the address was last seen on air rather than when
it was first resolved.
hci_add_irk() can install a live address as well: when SMP receives a
peer's IRK over a connection established to its RPA, which is the usual
way the cache is first populated, it passes that address along. Stamp
it there too, so a non-zero rpa always carries a current time; the mgmt
load path, which passes BDADDR_ANY, leaves the stamp alone, and readers
check the address before the time either way.
The store races with concurrent readers the same way the existing
bacpy() to irk->rpa does. Both are benign -- a reader either sees the
previous value or the new one -- but use WRITE_ONCE() to say so.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Radek Podgorny <radek@podgorny.cz>
---
include/net/bluetooth/hci_core.h | 4 ++++
net/bluetooth/hci_core.c | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index c12cd6873f65..8308ef6160d3 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -212,6 +212,10 @@ struct smp_irk {
struct list_head list;
struct rcu_head rcu;
bdaddr_t rpa;
+ /* when rpa was last seen on air; used to decide whether the peer is
+ * currently advertising an RPA or its identity address
+ */
+ unsigned long rpa_jiffies;
bdaddr_t bdaddr;
u8 addr_type;
u8 val[16];
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 66840df8c020..8ee26cb10276 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1179,6 +1179,7 @@ struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
rcu_read_lock();
list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
if (!bacmp(&irk->rpa, rpa)) {
+ WRITE_ONCE(irk->rpa_jiffies, jiffies);
irk_to_return = irk;
goto done;
}
@@ -1187,6 +1188,7 @@ struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
list_for_each_entry_rcu(irk, &hdev->identity_resolving_keys, list) {
if (smp_irk_matches(hdev, irk->val, rpa)) {
bacpy(&irk->rpa, rpa);
+ WRITE_ONCE(irk->rpa_jiffies, jiffies);
irk_to_return = irk;
goto done;
}
@@ -1331,6 +1333,8 @@ struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
memcpy(irk->val, val, 16);
bacpy(&irk->rpa, rpa);
+ if (bacmp(&irk->rpa, BDADDR_ANY))
+ WRITE_ONCE(irk->rpa_jiffies, jiffies);
return irk;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 0/2] Bluetooth: dial the peer's on-air address when we cannot resolve
@ 2026-09-07 23:20 Radek Podgorny
2026-09-07 23:20 ` [PATCH 1/2] Bluetooth: record when an IRK's RPA was last seen Radek Podgorny
2026-09-07 23:20 ` [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve Radek Podgorny
0 siblings, 2 replies; 9+ messages in thread
From: Radek Podgorny @ 2026-09-07 23:20 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz
Cc: linux-bluetooth, linux-kernel, Radek Podgorny
On a controller that cannot resolve private addresses, an outgoing LE
connection to a peer that is advertising an RPA goes out on the peer's
identity address and cannot succeed. It burns a full create-connection
timeout, and because such a controller also has no extended scanning it
cannot scan while it is initiating, so the adapter goes deaf to every other
device for the duration.
Patch 2 picks the address to put on air instead of assuming conn->dst.
Patch 1 is its prerequisite: choosing a cached RPA is only safe while that
RPA is still current, and nothing recorded when one was last seen.
Measured on a Raspberry Pi with two controllers, a CYW43438 as the central
and a Realtek dongle as the peer, Arch Linux ARM 7.2, BlueZ 5.87. The peer
advertises an RPA generated from a fixed IRK that is also loaded into the
central, so advertisements resolve and the conditions the patches care about
hold. Numbers are in patch 2.
Neither of those adapters reports LL Privacy, so the branch that defers to a
controller's resolving list was measured separately, on an Intel controller
that does. With the peer programmed into that controller's resolving list the
host puts the identity address into LE Extended Create Connection, and the
controller resolves it and connects:
LE Enhanced Connection Complete (0x0a)
Status: Success (0x00)
Peer address type: Resolved Public (0x02)
Peer address: 3C:78:95:78:37:C3
Peer resolvable private address: 6D:CA:DB:24:14:E9 (Resolvable)
Before the peer is in the resolving list, the same setup dials the peer's RPA
instead. So both directions of that branch are covered: the host defers when
the controller can translate, and substitutes when it cannot.
What this series does not establish:
- Patch 1 has no independent observable. It ships as patch 2's
prerequisite and its effect is only visible through patch 2's behaviour.
- Three controllers, one peer, two kernel versions. The fallback branches
were exercised on a CYW43438, the resolving-list branch on one Intel
controller. The peer is a Linux host running BlueZ rather than an
embedded peripheral, so nothing here speaks to other stacks.
Two further patches were carried in earlier revisions of this work and
dropped after each was built and measured on its own; neither turned out to
have a reachable effect. An earlier form of one of them also corrupted
Secure Connections pairing. They are not in this series.
Tooling: written with Claude (claude-opus-5) assisting, per
Documentation/process/coding-assistants.rst, hence the Assisted-by tags.
The session covered reading the existing address handling, drafting the
patches, and analysing the btmon captures. Every hypothesis that could be
tested on hardware was tested there, and the ones that failed were dropped
rather than argued. All patches are checkpatch --strict clean and build
without new warnings.
Radek Podgorny (2):
Bluetooth: record when an IRK's RPA was last seen
Bluetooth: put the peer's on-air address on air when we cannot resolve
include/net/bluetooth/hci_core.h | 4 ++
net/bluetooth/hci_core.c | 4 ++
net/bluetooth/hci_sync.c | 82 +++++++++++++++++++++++++++++---
3 files changed, 83 insertions(+), 7 deletions(-)
base-commit: 755cf7adf8dd2d12627cb7de223d35b12228e2f5
--
2.55.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: Bluetooth: dial the peer's on-air address when we cannot resolve
2026-09-07 23:20 ` [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve Radek Podgorny
@ 2026-09-08 0:03 ` bluez.test.bot
2026-09-08 14:00 ` [PATCH 2/2] Bluetooth: put the peer's on-air address on air " Luiz Augusto von Dentz
2026-09-08 16:07 ` Bluetooth: dial the peer's on-air address " bluez.test.bot
2 siblings, 0 replies; 9+ messages in thread
From: bluez.test.bot @ 2026-09-08 0:03 UTC (permalink / raw)
To: linux-bluetooth, radek
[-- Attachment #1: Type: text/plain, Size: 382 bytes --]
This is an automated email and please do not reply to this email.
Dear Submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.
----- Output -----
Please resolve the issue and submit the patches again.
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve
2026-09-07 23:20 ` [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve Radek Podgorny
2026-09-08 0:03 ` Bluetooth: dial the peer's on-air address " bluez.test.bot
@ 2026-09-08 14:00 ` Luiz Augusto von Dentz
2026-09-08 20:40 ` Radek Podgorny
2026-09-08 16:07 ` Bluetooth: dial the peer's on-air address " bluez.test.bot
2 siblings, 1 reply; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2026-09-08 14:00 UTC (permalink / raw)
To: Radek Podgorny; +Cc: Marcel Holtmann, linux-bluetooth, linux-kernel
Hi Radek,
On Mon, Sep 7, 2026 at 7:21 PM Radek Podgorny <radek@podgorny.cz> wrote:
>
> An identity address only reaches a peer that is advertising an RPA if the
> controller resolves on our behalf. Where it cannot, the host has to put the
> peer's on-air address on air itself.
>
> hci_connect_le() used to do exactly that, swapping the caller's identity
> address for the peer's cached RPA before creating the connection:
>
> irk = hci_find_irk_by_addr(hdev, dst, dst_type);
> if (irk && bacmp(&irk->rpa, BDADDR_ANY)) {
> dst = &irk->rpa;
> dst_type = ADDR_LE_DEV_RANDOM;
> }
>
> __hci_conn_add() now resolves that RPA back to the identity address when it
> stores it, so the swap no longer survives into conn->dst and the identity
> address is what goes out. Storing the identity is right for host
> bookkeeping, but nothing translates it again on the way to the controller.
>
> A peer advertising an RPA cannot answer an identity address, so the attempt
> burns a full create-connection timeout. That is not merely a slow connect:
> a controller without extended scanning cannot scan while it is initiating,
> so every dead attempt also takes the scanner off the air for the whole
> timeout.
>
> Measured on a CYW43438, which reports neither LL Privacy nor extended
> advertising (LE features 3f 00 00 08 00 00 00 00), against a peer
> advertising a resolvable private address the host holds the IRK for, with
> the connection requested on the peer's identity address:
>
> before: LE Create Connection to the identity address, public type
> 1.61s -> 22.07s, then LE Create Connection Cancel
> LE Connection Complete: Unknown Connection Identifier (0x02)
> after: LE Create Connection to the peer's RPA, random type
> LE Connection Complete: Success
Ok, the problem is then that we are trying to an indentity address to
connect when LL Privacy is not supported, so we probably can just
revert to use the private address at hci_conn_add in LL Pirvacy is not
supported or we didn't program the address in the resolving list.
> Advertising reports reaching the host per second, same window, same five
> unrelated devices on the adapter:
>
> before 1s:2 [nothing from 2s through 21s] 22s:5 23s:3
> after 0s:11 1s:5 2s:2 3s:5 4s:3 5s:4 ... 21s:2 22s:1 23s:2
>
> One dead connect costs twenty seconds of scanning for every device on the
> adapter, not just the one being dialled. Enough of them in a row and the
> host's advertisement monitor sees nothing for long enough to power-cycle
> the adapter, dropping every link on it.
>
> Choose the address to dial rather than assuming conn->dst:
>
> - if the controller is resolving and this peer's IRK is programmed, the
> identity address is correct and the resolving list translates it.
> Testing ll_privacy_capable() alone is not enough: it reports the
> feature bit, not whether resolution is switched on and not whether this
> peer is in the list. Resolution is cleared with the other volatile
> flags on power-off and switched off again while suspend pauses
> scanning, and a peer's IRK is only programmed along the accept list
> path, so a direct-connect target, a peer without
> HCI_CONN_FLAG_ADDRESS_RESOLUTION, and one that did not fit in a full
> list are all absent from it;
> - a dst that is already a private address is what the peer is on air with
> and needs no translation;
> - otherwise use the last RPA resolved for this peer, while it is still
> fresh. A stale RPA is worse than none: the peer has already rotated
> away from it.
>
> The first branch was measured on an Intel controller that does report LL
> Privacy. With the peer's IRK programmed into the controller's resolving
> list the host puts the identity address on air and the controller
> translates it, reporting Resolved Public with the peer's RPA
> 6D:CA:DB:24:14:E9 in LE Enhanced Connection Complete. With the peer
> absent from the list the same setup dials that RPA itself.
>
> The address is chosen once in hci_le_create_conn_sync() and handed to
> whichever command builder runs, the same way own_addr_type already is, so
> the two paths cannot disagree.
>
> Store the chosen address in conn->dst when it is not already there. The
> connection complete event names the address that was dialled and
> hci_conn_hash_lookup_role() finds a connection by conn->dst, so leaving the
> identity address behind would make the event miss this connection and add a
> second one while this one waits out its timeout. le_conn_complete_evt()
> resolves the address back to the identity once the link is up, which is the
> same round trip hci_connect_le() has always relied on.
>
> Fixes: 14b06c3a88f7 ("Bluetooth: HCI: Always use the identity address when initializing a connection")
> Assisted-by: Claude:claude-opus-5
> Signed-off-by: Radek Podgorny <radek@podgorny.cz>
> ---
> net/bluetooth/hci_sync.c | 82 ++++++++++++++++++++++++++++++++++++----
> 1 file changed, 75 insertions(+), 7 deletions(-)
>
> diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
> index 5376ade2cdc1..136d801baa85 100644
> --- a/net/bluetooth/hci_sync.c
> +++ b/net/bluetooth/hci_sync.c
> @@ -6794,8 +6794,60 @@ static void set_ext_conn_params(struct hci_conn *conn,
> p->max_ce_len = cpu_to_le16(0x0000);
> }
>
> +/* An RPA resolved more recently than this is taken to still be what the peer
> + * is on air with. The spec-recommended rotation period is the best estimate
> + * the host has; a stale RPA costs one failed connect, while falling back to an
> + * identity address the controller cannot translate costs a full
> + * create-connection timeout that cannot succeed.
> + */
> +#define HCI_RPA_FRESH_TIMEOUT secs_to_jiffies(HCI_DEFAULT_RPA_TIMEOUT)
Not really following why this is needed though, we always scan before
connecting, so perhaps we need to update the rpa whenever we resolve
at process_adv_report:
/* Check if we need to convert to identity address */
irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
if (irk) {
bdaddr = &irk->bdaddr;
bdaddr_type = irk->addr_type;
}
So we do translate the advertisements to back to the identity address,
but we don't update the irk->rpa, which is probably what shall be used
in case the controller cannot resolve.
> +/* Pick the address to put on air for an outgoing LE connection.
> + *
> + * hci_conn_add() stores the peer identity address whenever an IRK resolves,
> + * which is what host bookkeeping wants but not what reaches the peer: an
> + * identity address only gets there if the controller resolves on our behalf.
> + * Prefer an address the peer has actually been seen using.
> + *
> + * This function requires the caller holds hdev->lock.
> + */
> +static void hci_conn_select_peer_addr(struct hci_dev *hdev,
> + struct hci_conn *conn,
> + bdaddr_t *peer_addr, u8 *peer_addr_type)
> +{
> + struct smp_irk *irk;
> +
> + /* conn->dst is right both when the controller translates it for us and
> + * when it is already a private address.
> + */
> + bacpy(peer_addr, &conn->dst);
> + *peer_addr_type = conn->dst_type;
> +
> + /* Supporting LL Privacy is not enough: resolution has to be switched on
> + * and this peer's IRK actually programmed, which only happens along the
> + * accept list path.
> + */
> + if (hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION) &&
> + hci_bdaddr_list_lookup_with_irk(&hdev->le_resolv_list, &conn->dst,
> + conn->dst_type))
> + return;
> +
> + if (hci_bdaddr_is_rpa(&conn->dst, conn->dst_type))
> + return;
> +
> + irk = hci_find_irk_by_addr(hdev, &conn->dst, conn->dst_type);
> + if (!irk || !bacmp(&irk->rpa, BDADDR_ANY) ||
> + !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
> + HCI_RPA_FRESH_TIMEOUT))
> + return;
> +
> + bacpy(peer_addr, &irk->rpa);
> + *peer_addr_type = ADDR_LE_DEV_RANDOM;
> +}
> +
> static int hci_le_ext_create_conn_sync(struct hci_dev *hdev,
> - struct hci_conn *conn, u8 own_addr_type)
> + struct hci_conn *conn, u8 own_addr_type,
> + bdaddr_t *peer_addr, u8 peer_addr_type)
> {
> struct hci_cp_le_ext_create_conn *cp;
> struct hci_cp_le_ext_conn_param *p;
> @@ -6807,8 +6859,8 @@ static int hci_le_ext_create_conn_sync(struct hci_dev *hdev,
>
> memset(cp, 0, sizeof(*cp));
>
> - bacpy(&cp->peer_addr, &conn->dst);
> - cp->peer_addr_type = conn->dst_type;
> + bacpy(&cp->peer_addr, peer_addr);
> + cp->peer_addr_type = peer_addr_type;
> cp->own_addr_type = own_addr_type;
>
> plen = sizeof(*cp);
> @@ -6849,7 +6901,8 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
> {
> struct hci_cp_le_create_conn cp;
> struct hci_conn_params *params;
> - u8 own_addr_type;
> + u8 own_addr_type, peer_addr_type;
> + bdaddr_t peer_addr;
> int err;
> struct hci_conn *conn = data;
>
> @@ -6927,9 +6980,24 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
> */
> set_bit(HCI_CONN_CREATE, &conn->flags);
>
> + hci_dev_lock(hdev);
> + hci_conn_select_peer_addr(hdev, conn, &peer_addr, &peer_addr_type);
> +
> + /* The connection complete event names the address that was dialled and
> + * hci_conn_hash_lookup_role() finds a connection by conn->dst, so
> + * leaving the identity address there would make the event miss this
> + * connection and build a second one. Follow the dialled address
> + * instead; le_conn_complete_evt() resolves it back once the link is
> + * up.
> + */
> + bacpy(&conn->dst, &peer_addr);
> + conn->dst_type = peer_addr_type;
> + hci_dev_unlock(hdev);
> +
> /* Send command LE Extended Create Connection if supported */
> if (use_ext_conn(hdev)) {
> - err = hci_le_ext_create_conn_sync(hdev, conn, own_addr_type);
> + err = hci_le_ext_create_conn_sync(hdev, conn, own_addr_type,
> + &peer_addr, peer_addr_type);
> goto done;
> }
>
> @@ -6938,8 +7006,8 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
> cp.scan_interval = cpu_to_le16(hdev->le_scan_int_connect);
> cp.scan_window = cpu_to_le16(hdev->le_scan_window_connect);
>
> - bacpy(&cp.peer_addr, &conn->dst);
> - cp.peer_addr_type = conn->dst_type;
> + bacpy(&cp.peer_addr, &peer_addr);
> + cp.peer_addr_type = peer_addr_type;
> cp.own_address_type = own_addr_type;
> cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
> cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
> --
> 2.55.0
>
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: Bluetooth: dial the peer's on-air address when we cannot resolve
2026-09-07 23:20 ` [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve Radek Podgorny
2026-09-08 0:03 ` Bluetooth: dial the peer's on-air address " bluez.test.bot
2026-09-08 14:00 ` [PATCH 2/2] Bluetooth: put the peer's on-air address on air " Luiz Augusto von Dentz
@ 2026-09-08 16:07 ` bluez.test.bot
2 siblings, 0 replies; 9+ messages in thread
From: bluez.test.bot @ 2026-09-08 16:07 UTC (permalink / raw)
To: linux-bluetooth, radek
[-- Attachment #1: Type: text/plain, Size: 49614 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/series/1160052/
---Test result---
Test Summary:
CheckPatch PASS 1.35 seconds
VerifyFixes PASS 0.07 seconds
VerifySignedoff PASS 0.07 seconds
GitLint FAIL 0.42 seconds
SubjectPrefix PASS 0.14 seconds
BuildKernel PASS 28.48 seconds
CheckAllWarning PASS 30.70 seconds
CheckSparse PASS 29.58 seconds
BuildKernel32 PASS 26.87 seconds
CheckKernelLLVM SKIP 0.00 seconds
TestRunnerSetup PASS 511.40 seconds
TestRunner_l2cap-tester PASS 66.12 seconds
TestRunner_iso-tester PASS 110.36 seconds
TestRunner_bnep-tester PASS 19.53 seconds
TestRunner_mgmt-tester FAIL 230.42 seconds
TestRunner_rfcomm-tester PASS 25.61 seconds
TestRunner_sco-tester PASS 31.97 seconds
TestRunner_ioctl-tester PASS 27.26 seconds
TestRunner_mesh-tester FAIL 26.92 seconds
TestRunner_smp-tester PASS 24.39 seconds
TestRunner_userchan-tester PASS 20.81 seconds
TestRunner_6lowpan-tester PASS 24.62 seconds
IncrementalBuild FAIL 22.06 seconds
Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve
10: B3 Line contains hard tab characters (\t): " irk = hci_find_irk_by_addr(hdev, dst, dst_type);"
11: B3 Line contains hard tab characters (\t): " if (irk && bacmp(&irk->rpa, BDADDR_ANY)) {"
12: B3 Line contains hard tab characters (\t): " dst = &irk->rpa;"
13: B3 Line contains hard tab characters (\t): " dst_type = ADDR_LE_DEV_RANDOM;"
14: B3 Line contains hard tab characters (\t): " }"
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 501, Passed: 496 (99.0%), Failed: 1, Not Run: 4
Failed Test Cases
Read Exp Feature - Success Failed 0.248 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0
Failed Test Cases
Mesh - Send cancel - 1 Timed out 2.598 seconds
Mesh - Send cancel - 2 Timed out 1.987 seconds
##############################
Test: IncrementalBuild - FAIL
Desc: Incremental build with the patches in the series
Output:
In file included from ./include/linux/bitops.h:7,
from ./include/linux/fwnode.h:18,
from ./include/linux/property.h:17,
from net/bluetooth/hci_sync.c:9:
net/bluetooth/hci_sync.c: In function ‘hci_conn_select_peer_addr’:
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
./include/asm-generic/rwonce.h:44:42: note: in expansion of macro ‘__unqual_scalar_typeof’
44 | #define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
| ^~~~~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:50:2: note: in expansion of macro ‘__READ_ONCE’
50 | __READ_ONCE(x); \
| ^~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
./include/asm-generic/rwonce.h:50:2: note: in expansion of macro ‘__READ_ONCE’
50 | __READ_ONCE(x); \
| ^~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
./include/linux/typecheck.h:12:18: warning: comparison of distinct pointer types lacks a cast
12 | (void)(&__dummy == &__dummy2); \
| ^~
./include/linux/jiffies.h:124:3: note: in expansion of macro ‘typecheck’
124 | (typecheck(unsigned long, a) && \
| ^~~~~~~~~
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
In file included from ./include/linux/ktime.h:25,
from ./include/linux/poll.h:7,
from ./include/net/bluetooth/bluetooth.h:26,
from net/bluetooth/hci_sync.c:11:
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
./include/asm-generic/rwonce.h:44:42: note: in expansion of macro ‘__unqual_scalar_typeof’
44 | #define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
| ^~~~~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:50:2: note: in expansion of macro ‘__READ_ONCE’
50 | __READ_ONCE(x); \
| ^~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
./include/asm-generic/rwonce.h:50:2: note: in expansion of macro ‘__READ_ONCE’
50 | __READ_ONCE(x); \
| ^~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
make[4]: *** [scripts/Makefile.build:289: net/bluetooth/hci_sync.o] Error 1
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [scripts/Makefile.build:549: net/bluetooth] Error 2
make[2]: *** [scripts/Makefile.build:549: net] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/github/workspace/src/src/Makefile:2187: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
[2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve
In file included from ./include/linux/bitops.h:7,
from ./include/linux/fwnode.h:18,
from ./include/linux/property.h:17,
from net/bluetooth/hci_sync.c:9:
net/bluetooth/hci_sync.c: In function ‘hci_conn_select_peer_addr’:
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
./include/asm-generic/rwonce.h:44:42: note: in expansion of macro ‘__unqual_scalar_typeof’
44 | #define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
| ^~~~~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:50:2: note: in expansion of macro ‘__READ_ONCE’
50 | __READ_ONCE(x); \
| ^~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/typecheck.h:11:9: note: in definition of macro ‘typecheck’
11 | typeof(x) __dummy2; \
| ^
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
./include/asm-generic/rwonce.h:50:2: note: in expansion of macro ‘__READ_ONCE’
50 | __READ_ONCE(x); \
| ^~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
./include/linux/typecheck.h:12:18: warning: comparison of distinct pointer types lacks a cast
12 | (void)(&__dummy == &__dummy2); \
| ^~
./include/linux/jiffies.h:124:3: note: in expansion of macro ‘typecheck’
124 | (typecheck(unsigned long, a) && \
| ^~~~~~~~~
./include/linux/jiffies.h:134:26: note: in expansion of macro ‘time_after’
134 | #define time_before(a,b) time_after(b,a)
| ^~~~~~~~~~
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
In file included from ./include/linux/ktime.h:25,
from ./include/linux/poll.h:7,
from ./include/net/bluetooth/bluetooth.h:26,
from net/bluetooth/hci_sync.c:11:
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:21: note: in expansion of macro ‘__native_word’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
././include/linux/compiler_types.h:690:2: note: in expansion of macro ‘__compiletime_assert’
690 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~~~~~~~~~~~~
././include/linux/compiler_types.h:702:2: note: in expansion of macro ‘_compiletime_assert’
702 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:36:2: note: in expansion of macro ‘compiletime_assert’
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:49:2: note: in expansion of macro ‘compiletime_assert_rwonce_type’
49 | compiletime_assert_rwonce_type(x); \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
./include/asm-generic/rwonce.h:44:42: note: in expansion of macro ‘__unqual_scalar_typeof’
44 | #define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
| ^~~~~~~~~~~~~~~~~~~~~~
./include/asm-generic/rwonce.h:50:2: note: in expansion of macro ‘__READ_ONCE’
50 | __READ_ONCE(x); \
| ^~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
net/bluetooth/hci_sync.c:6840:41: error: ‘struct smp_irk’ has no member named ‘rpa_jiffies’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~
./include/linux/jiffies.h:126:18: note: in definition of macro ‘time_after’
126 | ((long)((b) - (a)) < 0))
| ^
net/bluetooth/hci_sync.c:6840:7: note: in expansion of macro ‘time_before’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~~~
./include/asm-generic/rwonce.h:50:2: note: in expansion of macro ‘__READ_ONCE’
50 | __READ_ONCE(x); \
| ^~~~~~~~~~~
net/bluetooth/hci_sync.c:6840:28: note: in expansion of macro ‘READ_ONCE’
6840 | !time_before(jiffies, READ_ONCE(irk->rpa_jiffies) +
| ^~~~~~~~~
make[4]: *** [scripts/Makefile.build:289: net/bluetooth/hci_sync.o] Error 1
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [scripts/Makefile.build:549: net/bluetooth] Error 2
make[2]: *** [scripts/Makefile.build:549: net] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/github/workspace/src/src/Makefile:2187: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
https://github.com/bluez/bluetooth-next/pull/715
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve
2026-09-08 14:00 ` [PATCH 2/2] Bluetooth: put the peer's on-air address on air " Luiz Augusto von Dentz
@ 2026-09-08 20:40 ` Radek Podgorny
2026-09-08 20:59 ` Luiz Augusto von Dentz
0 siblings, 1 reply; 9+ messages in thread
From: Radek Podgorny @ 2026-09-08 20:40 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Marcel Holtmann, Luiz Augusto von Dentz, linux-bluetooth,
linux-kernel
Hi Luiz,
On Tue, Sep 8, 2026 at 4:00 PM Luiz Augusto von Dentz wrote:
> Ok, the problem is then that we are trying to an indentity address to
> connect when LL Privacy is not supported, so we probably can just
> revert to use the private address at hci_conn_add in LL Pirvacy is not
> supported or we didn't program the address in the resolving list.
Agreed, that is the better place. v2 does exactly that: __hci_conn_add()
keeps the RPA that hci_connect_le() swapped in unless
HCI_LL_RPA_RESOLUTION is set and the peer's identity is actually in
le_resolv_list. All of the hci_sync.c changes are gone;
le_conn_complete_evt() already resolves conn->dst back to the identity
once the link is up, so the round trip comes for free.
One cost worth naming: with the RPA in conn->dst from creation,
hci_conn_params_lookup() in hci_le_create_conn_sync() misses the
identity-keyed conn params and the connection falls back to the default
intervals. That is the pre-14b06c3a88f7 behaviour, so nothing regresses
relative to the code this fixes; if it matters it can be done on top by
resolving through hci_get_irk() the way hci_connect_le_scan_cleanup()
already does.
> Not really following why this is needed though, we always scan before
> connecting, so perhaps we need to update the rpa whenever we resolve
> at process_adv_report:
>
> /* Check if we need to convert to identity address */
> irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
> if (irk) {
> bdaddr = &irk->bdaddr;
> bdaddr_type = irk->addr_type;
> }
>
> So we do translate the advertisements to back to the identity address,
> but we don't update the irk->rpa, which is probably what shall be used
> in case the controller cannot resolve.
irk->rpa is already kept current on that path, one call deeper than the
snippet: hci_get_irk() routes any RPA to hci_find_irk_by_rpa(), whose
second loop does
if (smp_irk_matches(hdev, irk->val, rpa)) {
bacpy(&irk->rpa, rpa);
so every advertising report the host resolves refreshes the cached RPA,
including across a rotation. That is what the old swap in
hci_connect_le() fed on, and it still runs today.
Which also answers the timestamp question. Since every
scan-then-connect path refreshes irk->rpa from the report that triggered
the connect, the freshness check only matters for a peer that
distributed an IRK, used RPAs, and later went back to advertising its
identity address - the cached RPA then stays stale forever and keeps
being dialled. That corner predates 14b06c3a88f7 and has shipped that
way for years, so I have dropped the rpa_jiffies patch entirely; it can
come back as a separate change if that corner is ever worth closing.
v2 follows as a single patch.
Radek
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve
2026-09-08 20:40 ` Radek Podgorny
@ 2026-09-08 20:59 ` Luiz Augusto von Dentz
2026-09-08 22:28 ` Radek Podgorny
0 siblings, 1 reply; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2026-09-08 20:59 UTC (permalink / raw)
To: Radek Podgorny
Cc: Marcel Holtmann, Luiz Augusto von Dentz, linux-bluetooth,
linux-kernel
Hi Radek,
On Tue, Sep 8, 2026 at 4:41 PM Radek Podgorny <radek@podgorny.cz> wrote:
>
> Hi Luiz,
>
> On Tue, Sep 8, 2026 at 4:00 PM Luiz Augusto von Dentz wrote:
>
> > Ok, the problem is then that we are trying to an indentity address to
> > connect when LL Privacy is not supported, so we probably can just
> > revert to use the private address at hci_conn_add in LL Pirvacy is not
> > supported or we didn't program the address in the resolving list.
>
> Agreed, that is the better place. v2 does exactly that: __hci_conn_add()
> keeps the RPA that hci_connect_le() swapped in unless
> HCI_LL_RPA_RESOLUTION is set and the peer's identity is actually in
> le_resolv_list. All of the hci_sync.c changes are gone;
> le_conn_complete_evt() already resolves conn->dst back to the identity
> once the link is up, so the round trip comes for free.
>
> One cost worth naming: with the RPA in conn->dst from creation,
> hci_conn_params_lookup() in hci_le_create_conn_sync() misses the
> identity-keyed conn params and the connection falls back to the default
> intervals. That is the pre-14b06c3a88f7 behaviour, so nothing regresses
> relative to the code this fixes; if it matters it can be done on top by
> resolving through hci_get_irk() the way hci_connect_le_scan_cleanup()
> already does.
That probably worth fixing, but yes it can be done on top.
> > Not really following why this is needed though, we always scan before
> > connecting, so perhaps we need to update the rpa whenever we resolve
> > at process_adv_report:
> >
> > /* Check if we need to convert to identity address */
> > irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
> > if (irk) {
> > bdaddr = &irk->bdaddr;
> > bdaddr_type = irk->addr_type;
> > }
> >
> > So we do translate the advertisements to back to the identity address,
> > but we don't update the irk->rpa, which is probably what shall be used
> > in case the controller cannot resolve.
>
> irk->rpa is already kept current on that path, one call deeper than the
> snippet: hci_get_irk() routes any RPA to hci_find_irk_by_rpa(), whose
> second loop does
>
> if (smp_irk_matches(hdev, irk->val, rpa)) {
> bacpy(&irk->rpa, rpa);
>
> so every advertising report the host resolves refreshes the cached RPA,
> including across a rotation. That is what the old swap in
> hci_connect_le() fed on, and it still runs today.
>
> Which also answers the timestamp question. Since every
> scan-then-connect path refreshes irk->rpa from the report that triggered
> the connect, the freshness check only matters for a peer that
> distributed an IRK, used RPAs, and later went back to advertising its
> identity address - the cached RPA then stays stale forever and keeps
> being dialled. That corner predates 14b06c3a88f7 and has shipped that
> way for years, so I have dropped the rpa_jiffies patch entirely; it can
> come back as a separate change if that corner is ever worth closing.
But if it advertises using the identity, we should connect using the
identity as well; there's no reason to use the stale RPA if the peer
somehow disabled its privacy.
> v2 follows as a single patch.
>
> Radek
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve
2026-09-08 20:59 ` Luiz Augusto von Dentz
@ 2026-09-08 22:28 ` Radek Podgorny
0 siblings, 0 replies; 9+ messages in thread
From: Radek Podgorny @ 2026-09-08 22:28 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Marcel Holtmann, Luiz Augusto von Dentz, linux-bluetooth,
linux-kernel
Hi Luiz,
On Tue, Sep 8, 2026 at 10:59 PM Luiz Augusto von Dentz wrote:
> > One cost worth naming: with the RPA in conn->dst from creation,
> > hci_conn_params_lookup() in hci_le_create_conn_sync() misses the
> > identity-keyed conn params [...]
>
> That probably worth fixing, but yes it can be done on top.
Ack, I will send that separately. For the record it is only the lookup in
hci_le_create_conn_sync(): the other conn->dst-keyed lookups run on an
established link, by which point le_conn_complete_evt() has already put the
identity address back, so they never see an RPA.
> But if it advertises using the identity, we should connect using the
> identity as well; there's no reason to use the stale RPA if the peer
> somehow disabled its privacy.
You are right, and my apologies for missing it: v2 as sent does not just
leave that corner unhandled, it makes it worse than what it replaced. I had
the freshness window fixed in my head as the answer to the stale RPA, so
when the timestamp went away I dismissed the case along with it instead of
looking at what the case actually needed. It needed invalidation, which the
timestamp was only approximating badly.
Concretely: nothing ever clears irk->rpa, and v2 removes the conversion in
__hci_conn_add() that was papering over that. The peer advertises its
identity, hci_connect_le() swaps the dead RPA back in, and every attempt
from then on is dialled at an address the peer has abandoned - a permanent
failure where the code v2 replaces would have connected.
So v3 adds the missing half of the cache maintenance ahead of the address
change. hci_find_irk_by_rpa() already refreshes irk->rpa when a report
resolves; nothing invalidates it when the peer stops using RPAs. In
process_adv_report(), in the else branch of the block you quoted first time
round:
irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
if (irk) {
bdaddr = &irk->bdaddr;
bdaddr_type = irk->addr_type;
} else {
irk = hci_find_irk_by_addr(hdev, bdaddr, bdaddr_type);
if (irk)
bacpy(&irk->rpa, BDADDR_ANY);
}
hci_find_irk_by_addr() matches only public and static random addresses, so
an unresolved RPA belonging to some other device cannot reach it. The cache
then means "the last address the peer was seen on is an RPA", which is what
the swap in hci_connect_le() has always assumed it meant.
That patch comes first in the series, so no commit in between leaves the
tree dialling a stale RPA. I did not tag it Fixes:: with __hci_conn_add()
still converting, the stale address is only reachable today through the
reuse branch of hci_connect_le(), and a stable backport on its own does not
seem warranted.
The address selection itself is unchanged from v2.
v3 follows.
Radek
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-09-08 22:29 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-07 23:20 [PATCH 0/2] Bluetooth: dial the peer's on-air address when we cannot resolve Radek Podgorny
2026-09-07 23:20 ` [PATCH 1/2] Bluetooth: record when an IRK's RPA was last seen Radek Podgorny
2026-09-07 23:20 ` [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve Radek Podgorny
2026-09-08 0:03 ` Bluetooth: dial the peer's on-air address " bluez.test.bot
2026-09-08 14:00 ` [PATCH 2/2] Bluetooth: put the peer's on-air address on air " Luiz Augusto von Dentz
2026-09-08 20:40 ` Radek Podgorny
2026-09-08 20:59 ` Luiz Augusto von Dentz
2026-09-08 22:28 ` Radek Podgorny
2026-09-08 16:07 ` Bluetooth: dial the peer's on-air address " bluez.test.bot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.