diff options
| author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2016-03-29 16:33:47 +0300 | 
|---|---|---|
| committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2016-03-29 16:33:47 +0300 | 
| commit | 8041dcc881c928134c546ae85e6e59e65804357c (patch) | |
| tree | be5d1c21af8cf38ac32ed8708396881aabd44d4e /net/bluetooth/hci_request.c | |
| parent | ed6069be7204541c1da532ad8bbf892e34513552 (diff) | |
| parent | f55532a0c0b8bb6148f4e07853b876ef73bc69ca (diff) | |
| download | linux-8041dcc881c928134c546ae85e6e59e65804357c.tar.xz | |
Merge tag 'v4.6-rc1' into for-linus-4.6
Linux 4.6-rc1
* tag 'v4.6-rc1': (12823 commits)
  Linux 4.6-rc1
  f2fs/crypto: fix xts_tweak initialization
  NTB: Remove _addr functions from ntb_hw_amd
  orangefs: fix orangefs_superblock locking
  orangefs: fix do_readv_writev() handling of error halfway through
  orangefs: have ->kill_sb() evict the VFS side of things first
  orangefs: sanitize ->llseek()
  orangefs-bufmap.h: trim unused junk
  orangefs: saner calling conventions for getting a slot
  orangefs_copy_{to,from}_bufmap(): don't pass bufmap pointer
  orangefs: get rid of readdir_handle_s
  thp: fix typo in khugepaged_scan_pmd()
  MAINTAINERS: fill entries for KASAN
  mm/filemap: generic_file_read_iter(): check for zero reads unconditionally
  kasan: test fix: warn if the UAF could not be detected in kmalloc_uaf2
  mm, kasan: stackdepot implementation. Enable stackdepot for SLAB
  arch, ftrace: for KASAN put hard/soft IRQ entries into separate sections
  mm, kasan: add GFP flags to KASAN API
  mm, kasan: SLAB support
  kasan: modify kmalloc_large_oob_right(), add kmalloc_pagealloc_oob_right()
  ...
Diffstat (limited to 'net/bluetooth/hci_request.c')
| -rw-r--r-- | net/bluetooth/hci_request.c | 56 | 
1 files changed, 50 insertions, 6 deletions
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index c78ee2dc9323..6e125d76df0d 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -771,6 +771,11 @@ static u8 update_white_list(struct hci_request *req)  	return 0x01;  } +static bool scan_use_rpa(struct hci_dev *hdev) +{ +	return hci_dev_test_flag(hdev, HCI_PRIVACY); +} +  void hci_req_add_le_passive_scan(struct hci_request *req)  {  	struct hci_cp_le_set_scan_param param_cp; @@ -785,7 +790,8 @@ void hci_req_add_le_passive_scan(struct hci_request *req)  	 * advertising with our address will be correctly reported  	 * by the controller.  	 */ -	if (hci_update_random_address(req, false, &own_addr_type)) +	if (hci_update_random_address(req, false, scan_use_rpa(hdev), +				      &own_addr_type))  		return;  	/* Adding or removing entries from the white list must @@ -866,6 +872,11 @@ static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance)  		if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))  			flags |= MGMT_ADV_FLAG_CONNECTABLE; +		if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) +			flags |= MGMT_ADV_FLAG_LIMITED_DISCOV; +		else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE)) +			flags |= MGMT_ADV_FLAG_DISCOV; +  		return flags;  	} @@ -878,6 +889,29 @@ static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance)  	return adv_instance->flags;  } +static bool adv_use_rpa(struct hci_dev *hdev, uint32_t flags) +{ +	/* If privacy is not enabled don't use RPA */ +	if (!hci_dev_test_flag(hdev, HCI_PRIVACY)) +		return false; + +	/* If basic privacy mode is enabled use RPA */ +	if (!hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY)) +		return true; + +	/* If limited privacy mode is enabled don't use RPA if we're +	 * both discoverable and bondable. +	 */ +	if ((flags & MGMT_ADV_FLAG_DISCOV) && +	    hci_dev_test_flag(hdev, HCI_BONDABLE)) +		return false; + +	/* We're neither bondable nor discoverable in the limited +	 * privacy mode, therefore use RPA. +	 */ +	return true; +} +  void __hci_req_enable_advertising(struct hci_request *req)  {  	struct hci_dev *hdev = req->hdev; @@ -911,7 +945,9 @@ void __hci_req_enable_advertising(struct hci_request *req)  	 * advertising is used. In that case it is fine to use a  	 * non-resolvable private address.  	 */ -	if (hci_update_random_address(req, !connectable, &own_addr_type) < 0) +	if (hci_update_random_address(req, !connectable, +				      adv_use_rpa(hdev, flags), +				      &own_addr_type) < 0)  		return;  	memset(&cp, 0, sizeof(cp)); @@ -1325,7 +1361,7 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)  }  int hci_update_random_address(struct hci_request *req, bool require_privacy, -			      u8 *own_addr_type) +			      bool use_rpa, u8 *own_addr_type)  {  	struct hci_dev *hdev = req->hdev;  	int err; @@ -1334,7 +1370,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,  	 * current RPA has expired or there is something else than  	 * the current RPA in use, then generate a new one.  	 */ -	if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { +	if (use_rpa) {  		int to;  		*own_addr_type = ADDR_LE_DEV_RANDOM; @@ -1596,9 +1632,16 @@ static int discoverable_update(struct hci_request *req, unsigned long opt)  	/* Advertising instances don't use the global discoverable setting, so  	 * only update AD if advertising was enabled using Set Advertising.  	 */ -	if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) +	if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) {  		__hci_req_update_adv_data(req, 0x00); +		/* Discoverable mode affects the local advertising +		 * address in limited privacy mode. +		 */ +		if (hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY)) +			__hci_req_enable_advertising(req); +	} +  	hci_dev_unlock(hdev);  	return 0; @@ -1941,7 +1984,8 @@ static int active_scan(struct hci_request *req, unsigned long opt)  	 * address (when privacy feature has been enabled) or non-resolvable  	 * private address.  	 */ -	err = hci_update_random_address(req, true, &own_addr_type); +	err = hci_update_random_address(req, true, scan_use_rpa(hdev), +					&own_addr_type);  	if (err < 0)  		own_addr_type = ADDR_LE_DEV_PUBLIC;  | 
