@@ -702,6 +702,31 @@ static const struct file_operations force_static_address_fops = {
702
702
.llseek = default_llseek ,
703
703
};
704
704
705
+ static int white_list_show (struct seq_file * f , void * ptr )
706
+ {
707
+ struct hci_dev * hdev = f -> private ;
708
+ struct bdaddr_list * b ;
709
+
710
+ hci_dev_lock (hdev );
711
+ list_for_each_entry (b , & hdev -> le_white_list , list )
712
+ seq_printf (f , "%pMR (type %u)\n" , & b -> bdaddr , b -> bdaddr_type );
713
+ hci_dev_unlock (hdev );
714
+
715
+ return 0 ;
716
+ }
717
+
718
+ static int white_list_open (struct inode * inode , struct file * file )
719
+ {
720
+ return single_open (file , white_list_show , inode -> i_private );
721
+ }
722
+
723
+ static const struct file_operations white_list_fops = {
724
+ .open = white_list_open ,
725
+ .read = seq_read ,
726
+ .llseek = seq_lseek ,
727
+ .release = single_release ,
728
+ };
729
+
705
730
static int identity_resolving_keys_show (struct seq_file * f , void * ptr )
706
731
{
707
732
struct hci_dev * hdev = f -> private ;
@@ -1786,6 +1811,8 @@ static int __hci_init(struct hci_dev *hdev)
1786
1811
1787
1812
debugfs_create_u8 ("white_list_size" , 0444 , hdev -> debugfs ,
1788
1813
& hdev -> le_white_list_size );
1814
+ debugfs_create_file ("white_list" , 0444 , hdev -> debugfs , hdev ,
1815
+ & white_list_fops );
1789
1816
debugfs_create_file ("identity_resolving_keys" , 0400 ,
1790
1817
hdev -> debugfs , hdev ,
1791
1818
& identity_resolving_keys_fops );
@@ -3294,6 +3321,67 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3294
3321
return mgmt_device_unblocked (hdev , bdaddr , type );
3295
3322
}
3296
3323
3324
+ struct bdaddr_list * hci_white_list_lookup (struct hci_dev * hdev ,
3325
+ bdaddr_t * bdaddr , u8 type )
3326
+ {
3327
+ struct bdaddr_list * b ;
3328
+
3329
+ list_for_each_entry (b , & hdev -> le_white_list , list ) {
3330
+ if (!bacmp (& b -> bdaddr , bdaddr ) && b -> bdaddr_type == type )
3331
+ return b ;
3332
+ }
3333
+
3334
+ return NULL ;
3335
+ }
3336
+
3337
+ void hci_white_list_clear (struct hci_dev * hdev )
3338
+ {
3339
+ struct list_head * p , * n ;
3340
+
3341
+ list_for_each_safe (p , n , & hdev -> le_white_list ) {
3342
+ struct bdaddr_list * b = list_entry (p , struct bdaddr_list , list );
3343
+
3344
+ list_del (p );
3345
+ kfree (b );
3346
+ }
3347
+ }
3348
+
3349
+ int hci_white_list_add (struct hci_dev * hdev , bdaddr_t * bdaddr , u8 type )
3350
+ {
3351
+ struct bdaddr_list * entry ;
3352
+
3353
+ if (!bacmp (bdaddr , BDADDR_ANY ))
3354
+ return - EBADF ;
3355
+
3356
+ entry = kzalloc (sizeof (struct bdaddr_list ), GFP_KERNEL );
3357
+ if (!entry )
3358
+ return - ENOMEM ;
3359
+
3360
+ bacpy (& entry -> bdaddr , bdaddr );
3361
+ entry -> bdaddr_type = type ;
3362
+
3363
+ list_add (& entry -> list , & hdev -> le_white_list );
3364
+
3365
+ return 0 ;
3366
+ }
3367
+
3368
+ int hci_white_list_del (struct hci_dev * hdev , bdaddr_t * bdaddr , u8 type )
3369
+ {
3370
+ struct bdaddr_list * entry ;
3371
+
3372
+ if (!bacmp (bdaddr , BDADDR_ANY ))
3373
+ return - EBADF ;
3374
+
3375
+ entry = hci_white_list_lookup (hdev , bdaddr , type );
3376
+ if (!entry )
3377
+ return - ENOENT ;
3378
+
3379
+ list_del (& entry -> list );
3380
+ kfree (entry );
3381
+
3382
+ return 0 ;
3383
+ }
3384
+
3297
3385
/* This function requires the caller holds hdev->lock */
3298
3386
struct hci_conn_params * hci_conn_params_lookup (struct hci_dev * hdev ,
3299
3387
bdaddr_t * addr , u8 addr_type )
@@ -3692,6 +3780,7 @@ struct hci_dev *hci_alloc_dev(void)
3692
3780
INIT_LIST_HEAD (& hdev -> long_term_keys );
3693
3781
INIT_LIST_HEAD (& hdev -> identity_resolving_keys );
3694
3782
INIT_LIST_HEAD (& hdev -> remote_oob_data );
3783
+ INIT_LIST_HEAD (& hdev -> le_white_list );
3695
3784
INIT_LIST_HEAD (& hdev -> le_conn_params );
3696
3785
INIT_LIST_HEAD (& hdev -> pend_le_conns );
3697
3786
INIT_LIST_HEAD (& hdev -> conn_hash .list );
@@ -3894,6 +3983,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
3894
3983
hci_smp_ltks_clear (hdev );
3895
3984
hci_smp_irks_clear (hdev );
3896
3985
hci_remote_oob_data_clear (hdev );
3986
+ hci_white_list_clear (hdev );
3897
3987
hci_conn_params_clear (hdev );
3898
3988
hci_pend_le_conns_clear (hdev );
3899
3989
hci_dev_unlock (hdev );
0 commit comments