Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: ISO: Attempt to resolve broadcast address

Broadcasters maybe using RPAs which can change over time and not
matching the address used as destination in the socket, so this
attempts to resolve the addresses then match with the socket
address, in case that uses an indentity address, or then match the
IRKs if both broadcaster and socket are using RPAs.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

+39 -19
+39 -19
net/bluetooth/iso.c
··· 87 87 88 88 typedef bool (*iso_sock_match_t)(struct sock *sk, void *data); 89 89 90 - static struct sock *iso_get_sock(bdaddr_t *src, bdaddr_t *dst, 91 - enum bt_sock_state state, 90 + static struct sock *iso_get_sock(struct hci_dev *hdev, bdaddr_t *src, 91 + bdaddr_t *dst, enum bt_sock_state state, 92 92 iso_sock_match_t match, void *data); 93 93 94 94 /* ---- ISO timers ---- */ ··· 638 638 * match func data - pass -1 to ignore 639 639 * Returns closest match. 640 640 */ 641 - static struct sock *iso_get_sock(bdaddr_t *src, bdaddr_t *dst, 642 - enum bt_sock_state state, 641 + static struct sock *iso_get_sock(struct hci_dev *hdev, bdaddr_t *src, 642 + bdaddr_t *dst, enum bt_sock_state state, 643 643 iso_sock_match_t match, void *data) 644 644 { 645 645 struct sock *sk = NULL, *sk1 = NULL; ··· 651 651 continue; 652 652 653 653 /* Match Broadcast destination */ 654 - if (bacmp(dst, BDADDR_ANY) && bacmp(&iso_pi(sk)->dst, dst)) 655 - continue; 654 + if (bacmp(dst, BDADDR_ANY) && bacmp(&iso_pi(sk)->dst, dst)) { 655 + struct smp_irk *irk1, *irk2; 656 + 657 + /* Check if destination is an RPA that we can resolve */ 658 + irk1 = hci_find_irk_by_rpa(hdev, dst); 659 + if (!irk1) 660 + continue; 661 + 662 + /* Match with identity address */ 663 + if (bacmp(&iso_pi(sk)->dst, &irk1->bdaddr)) { 664 + /* Check if socket destination address is also 665 + * an RPA and if the IRK matches. 666 + */ 667 + irk2 = hci_find_irk_by_rpa(hdev, 668 + &iso_pi(sk)->dst); 669 + if (!irk2 || irk1 != irk2) 670 + continue; 671 + } 672 + } 656 673 657 674 /* Use Match function if provided */ 658 675 if (match && !match(sk, data)) ··· 2029 2012 struct hci_ev_le_pa_sync_established *ev2 = NULL; 2030 2013 struct hci_ev_le_per_adv_report *ev3 = NULL; 2031 2014 struct hci_conn *hcon; 2015 + struct hci_dev *hdev; 2032 2016 2033 2017 BT_DBG("conn %p", conn); 2034 2018 ··· 2040 2022 if (!hcon) 2041 2023 return; 2042 2024 2025 + hdev = hcon->hdev; 2026 + 2043 2027 if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags)) { 2044 2028 /* A BIS slave hcon is notified to the ISO layer 2045 2029 * after the Command Complete for the LE Setup 2046 2030 * ISO Data Path command is received. Get the 2047 2031 * parent socket that matches the hcon BIG handle. 2048 2032 */ 2049 - parent = iso_get_sock(&hcon->src, &hcon->dst, 2033 + parent = iso_get_sock(hdev, &hcon->src, &hcon->dst, 2050 2034 BT_LISTEN, iso_match_big_hcon, 2051 2035 hcon); 2052 2036 } else if (test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) { ··· 2056 2036 HCI_EVT_LE_BIG_SYNC_ESTABLISHED); 2057 2037 2058 2038 /* Get reference to PA sync parent socket, if it exists */ 2059 - parent = iso_get_sock(&hcon->src, &hcon->dst, 2039 + parent = iso_get_sock(hdev, &hcon->src, &hcon->dst, 2060 2040 BT_LISTEN, 2061 2041 iso_match_pa_sync_flag, 2062 2042 NULL); 2063 2043 if (!parent && ev) 2064 - parent = iso_get_sock(&hcon->src, 2044 + parent = iso_get_sock(hdev, &hcon->src, 2065 2045 &hcon->dst, 2066 2046 BT_LISTEN, 2067 2047 iso_match_big, ev); ··· 2069 2049 ev2 = hci_recv_event_data(hcon->hdev, 2070 2050 HCI_EV_LE_PA_SYNC_ESTABLISHED); 2071 2051 if (ev2) 2072 - parent = iso_get_sock(&hcon->src, 2052 + parent = iso_get_sock(hdev, &hcon->src, 2073 2053 &hcon->dst, 2074 2054 BT_LISTEN, 2075 2055 iso_match_sid, ev2); ··· 2077 2057 ev3 = hci_recv_event_data(hcon->hdev, 2078 2058 HCI_EV_LE_PER_ADV_REPORT); 2079 2059 if (ev3) 2080 - parent = iso_get_sock(&hcon->src, 2060 + parent = iso_get_sock(hdev, &hcon->src, 2081 2061 &hcon->dst, 2082 2062 BT_LISTEN, 2083 2063 iso_match_sync_handle_pa_report, ··· 2085 2065 } 2086 2066 2087 2067 if (!parent) 2088 - parent = iso_get_sock(&hcon->src, BDADDR_ANY, 2068 + parent = iso_get_sock(hdev, &hcon->src, BDADDR_ANY, 2089 2069 BT_LISTEN, NULL, NULL); 2090 2070 2091 2071 if (!parent) ··· 2228 2208 */ 2229 2209 ev1 = hci_recv_event_data(hdev, HCI_EV_LE_PA_SYNC_ESTABLISHED); 2230 2210 if (ev1) { 2231 - sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_LISTEN, 2211 + sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_LISTEN, 2232 2212 iso_match_sid, ev1); 2233 2213 if (sk && !ev1->status) { 2234 2214 iso_pi(sk)->sync_handle = le16_to_cpu(ev1->handle); ··· 2240 2220 2241 2221 ev1a = hci_recv_event_data(hdev, HCI_EV_LE_PAST_RECEIVED); 2242 2222 if (ev1a) { 2243 - sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_LISTEN, 2223 + sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_LISTEN, 2244 2224 iso_match_sid_past, ev1a); 2245 2225 if (sk && !ev1a->status) { 2246 2226 iso_pi(sk)->sync_handle = le16_to_cpu(ev1a->sync_handle); ··· 2253 2233 ev2 = hci_recv_event_data(hdev, HCI_EVT_LE_BIG_INFO_ADV_REPORT); 2254 2234 if (ev2) { 2255 2235 /* Check if BIGInfo report has already been handled */ 2256 - sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_CONNECTED, 2236 + sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_CONNECTED, 2257 2237 iso_match_sync_handle, ev2); 2258 2238 if (sk) { 2259 2239 sock_put(sk); ··· 2262 2242 } 2263 2243 2264 2244 /* Try to get PA sync socket, if it exists */ 2265 - sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_CONNECT2, 2245 + sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_CONNECT2, 2266 2246 iso_match_sync_handle, ev2); 2267 2247 if (!sk) 2268 - sk = iso_get_sock(&hdev->bdaddr, bdaddr, 2248 + sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, 2269 2249 BT_LISTEN, 2270 2250 iso_match_sync_handle, 2271 2251 ev2); ··· 2304 2284 u8 *base; 2305 2285 struct hci_conn *hcon; 2306 2286 2307 - sk = iso_get_sock(&hdev->bdaddr, bdaddr, BT_LISTEN, 2287 + sk = iso_get_sock(hdev, &hdev->bdaddr, bdaddr, BT_LISTEN, 2308 2288 iso_match_sync_handle_pa_report, ev3); 2309 2289 if (!sk) 2310 2290 goto done; ··· 2354 2334 hcon->le_per_adv_data_len = 0; 2355 2335 } 2356 2336 } else { 2357 - sk = iso_get_sock(&hdev->bdaddr, BDADDR_ANY, 2337 + sk = iso_get_sock(hdev, &hdev->bdaddr, BDADDR_ANY, 2358 2338 BT_LISTEN, NULL, NULL); 2359 2339 } 2360 2340