Commit 14b06c3a authored by Luiz Augusto von Dentz's avatar Luiz Augusto von Dentz
Browse files

Bluetooth: HCI: Always use the identity address when initializing a connection



This makes sure hci_conn is initialized with the identity address if
a matching IRK exists which avoids the trouble of having to do it at
multiple places which seems to be missing (e.g. CIS, BIS and PA).

Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent d3413703
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1571,9 +1571,9 @@ int hci_le_create_cis_pending(struct hci_dev *hdev);
int hci_conn_check_create_cis(struct hci_conn *conn);

struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
			      u8 role, u16 handle);
			      u8 dst_type, u8 role, u16 handle);
struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
				    bdaddr_t *dst, u8 role);
				    bdaddr_t *dst, u8 dst_type, u8 role);
void hci_conn_del(struct hci_conn *conn);
void hci_conn_hash_flush(struct hci_dev *hdev);

+27 −16
Original line number Diff line number Diff line
@@ -922,10 +922,12 @@ static int hci_conn_hash_alloc_unset(struct hci_dev *hdev)
			       U16_MAX, GFP_ATOMIC);
}

static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type,
				       bdaddr_t *dst, u8 dst_type,
				       u8 role, u16 handle)
{
	struct hci_conn *conn;
	struct smp_irk *irk = NULL;

	switch (type) {
	case ACL_LINK:
@@ -937,12 +939,14 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
	case PA_LINK:
		if (!hdev->iso_mtu)
			return ERR_PTR(-ECONNREFUSED);
		irk = hci_get_irk(hdev, dst, dst_type);
		break;
	case LE_LINK:
		if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
			return ERR_PTR(-ECONNREFUSED);
		if (!hdev->le_mtu && hdev->acl_mtu < HCI_MIN_LE_MTU)
			return ERR_PTR(-ECONNREFUSED);
		irk = hci_get_irk(hdev, dst, dst_type);
		break;
	case SCO_LINK:
	case ESCO_LINK:
@@ -960,7 +964,15 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
	if (!conn)
		return ERR_PTR(-ENOMEM);

	/* If and IRK exists use its identity address */
	if (!irk) {
		bacpy(&conn->dst, dst);
		conn->dst_type = dst_type;
	} else {
		bacpy(&conn->dst, &irk->bdaddr);
		conn->dst_type = irk->addr_type;
	}

	bacpy(&conn->src, &hdev->bdaddr);
	conn->handle = handle;
	conn->hdev  = hdev;
@@ -1059,7 +1071,7 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t
}

struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
				    bdaddr_t *dst, u8 role)
				    bdaddr_t *dst, u8 dst_type, u8 role)
{
	int handle;

@@ -1069,16 +1081,16 @@ struct hci_conn *hci_conn_add_unset(struct hci_dev *hdev, int type,
	if (unlikely(handle < 0))
		return ERR_PTR(-ECONNREFUSED);

	return __hci_conn_add(hdev, type, dst, role, handle);
	return __hci_conn_add(hdev, type, dst, dst_type, role, handle);
}

struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
			      u8 role, u16 handle)
			      u8 dst_type, u8 role, u16 handle)
{
	if (handle > HCI_CONN_HANDLE_MAX)
		return ERR_PTR(-EINVAL);

	return __hci_conn_add(hdev, type, dst, role, handle);
	return __hci_conn_add(hdev, type, dst, dst_type, role, handle);
}

static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason)
@@ -1410,14 +1422,13 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
	if (conn) {
		bacpy(&conn->dst, dst);
	} else {
		conn = hci_conn_add_unset(hdev, LE_LINK, dst, role);
		conn = hci_conn_add_unset(hdev, LE_LINK, dst, dst_type, role);
		if (IS_ERR(conn))
			return conn;
		hci_conn_hold(conn);
		conn->pending_sec_level = sec_level;
	}

	conn->dst_type = dst_type;
	conn->sec_level = BT_SECURITY_LOW;
	conn->conn_timeout = conn_timeout;
	conn->le_adv_phy = phy;
@@ -1587,7 +1598,7 @@ static struct hci_conn *hci_add_bis(struct hci_dev *hdev, bdaddr_t *dst,
		     memcmp(conn->le_per_adv_data, base, base_len)))
		return ERR_PTR(-EADDRINUSE);

	conn = hci_conn_add_unset(hdev, BIS_LINK, dst, HCI_ROLE_MASTER);
	conn = hci_conn_add_unset(hdev, BIS_LINK, dst, 0, HCI_ROLE_MASTER);
	if (IS_ERR(conn))
		return conn;

@@ -1633,7 +1644,8 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,

	BT_DBG("requesting refresh of dst_addr");

	conn = hci_conn_add_unset(hdev, LE_LINK, dst, HCI_ROLE_MASTER);
	conn = hci_conn_add_unset(hdev, LE_LINK, dst, dst_type,
				  HCI_ROLE_MASTER);
	if (IS_ERR(conn))
		return conn;

@@ -1644,7 +1656,6 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,

	conn->state = BT_CONNECT;
	set_bit(HCI_CONN_SCANNING, &conn->flags);
	conn->dst_type = dst_type;
	conn->sec_level = BT_SECURITY_LOW;
	conn->pending_sec_level = sec_level;
	conn->conn_timeout = conn_timeout;
@@ -1681,7 +1692,8 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,

	acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
	if (!acl) {
		acl = hci_conn_add_unset(hdev, ACL_LINK, dst, HCI_ROLE_MASTER);
		acl = hci_conn_add_unset(hdev, ACL_LINK, dst, 0,
					 HCI_ROLE_MASTER);
		if (IS_ERR(acl))
			return acl;
	}
@@ -1750,7 +1762,7 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,

	sco = hci_conn_hash_lookup_ba(hdev, type, dst);
	if (!sco) {
		sco = hci_conn_add_unset(hdev, type, dst, HCI_ROLE_MASTER);
		sco = hci_conn_add_unset(hdev, type, dst, 0, HCI_ROLE_MASTER);
		if (IS_ERR(sco)) {
			hci_conn_drop(acl);
			return sco;
@@ -1942,7 +1954,7 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
	cis = hci_conn_hash_lookup_cis(hdev, dst, dst_type, qos->ucast.cig,
				       qos->ucast.cis);
	if (!cis) {
		cis = hci_conn_add_unset(hdev, CIS_LINK, dst,
		cis = hci_conn_add_unset(hdev, CIS_LINK, dst, dst_type,
					 HCI_ROLE_MASTER);
		if (IS_ERR(cis))
			return cis;
@@ -2133,12 +2145,11 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,

	bt_dev_dbg(hdev, "dst %pMR type %d sid %d", dst, dst_type, sid);

	conn = hci_conn_add_unset(hdev, PA_LINK, dst, HCI_ROLE_SLAVE);
	conn = hci_conn_add_unset(hdev, PA_LINK, dst, dst_type, HCI_ROLE_SLAVE);
	if (IS_ERR(conn))
		return conn;

	conn->iso_qos = *qos;
	conn->dst_type = dst_type;
	conn->sid = sid;
	conn->state = BT_LISTEN;
	conn->conn_timeout = msecs_to_jiffies(qos->bcast.sync_timeout * 10);
+10 −10
Original line number Diff line number Diff line
@@ -2267,7 +2267,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
	} else {
		if (!conn) {
			conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr,
						  HCI_ROLE_MASTER);
						  0, HCI_ROLE_MASTER);
			if (IS_ERR(conn))
				bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
		}
@@ -3123,7 +3123,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
						      &ev->bdaddr,
						      BDADDR_BREDR)) {
			conn = hci_conn_add_unset(hdev, ev->link_type,
						  &ev->bdaddr, HCI_ROLE_SLAVE);
						  &ev->bdaddr, 0,
						  HCI_ROLE_SLAVE);
			if (IS_ERR(conn)) {
				bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
				goto unlock;
@@ -3299,7 +3300,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
			&ev->bdaddr);
	if (!conn) {
		conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr,
		conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr, 0,
					  HCI_ROLE_SLAVE);
		if (IS_ERR(conn)) {
			bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
@@ -5670,14 +5671,13 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
		if (status)
			goto unlock;

		conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, role);
		conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, bdaddr_type,
					  role);
		if (IS_ERR(conn)) {
			bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
			goto unlock;
		}

		conn->dst_type = bdaddr_type;

		/* If we didn't have a hci_conn object previously
		 * but we're in central role this must be something
		 * initiated using an accept list. Since accept list based
@@ -5982,7 +5982,7 @@ static void hci_le_past_received_evt(struct hci_dev *hdev, void *data,
		goto unlock;

	/* Add connection to indicate PA sync event */
	pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY,
	pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY, 0,
				     HCI_ROLE_SLAVE);

	if (IS_ERR(pa_sync))
@@ -6515,7 +6515,7 @@ static void hci_le_pa_sync_established_evt(struct hci_dev *hdev, void *data,
		goto unlock;

	/* Add connection to indicate PA sync event */
	pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY,
	pa_sync = hci_conn_add_unset(hdev, PA_LINK, BDADDR_ANY, 0,
				     HCI_ROLE_SLAVE);

	if (IS_ERR(pa_sync))
@@ -6956,7 +6956,7 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data,

	cis = hci_conn_hash_lookup_handle(hdev, cis_handle);
	if (!cis) {
		cis = hci_conn_add(hdev, CIS_LINK, &acl->dst,
		cis = hci_conn_add(hdev, CIS_LINK, &acl->dst, acl->dst_type,
				   HCI_ROLE_SLAVE, cis_handle);
		if (IS_ERR(cis)) {
			hci_le_reject_cis(hdev, ev->cis_handle);
@@ -7073,7 +7073,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
				bt_dev_dbg(hdev, "ignore too large handle %u", handle);
				continue;
			}
			bis = hci_conn_add(hdev, BIS_LINK, BDADDR_ANY,
			bis = hci_conn_add(hdev, BIS_LINK, BDADDR_ANY, 0,
					   HCI_ROLE_SLAVE, handle);
			if (IS_ERR(bis))
				continue;
+1 −1
Original line number Diff line number Diff line
@@ -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))