Re: [PATCH 2/2] Bluetooth: put the peer's on-air address on air when we cannot resolve
From: Radek Podgorny
Date: Tue Sep 08 2026 - 18:32:23 EST
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