@@ -38,10 +38,6 @@ struct mptcp_pm_add_entry {
38
38
u8 retrans_times ;
39
39
};
40
40
41
- /* max value of mptcp_addr_info.id */
42
- #define MAX_ADDR_ID U8_MAX
43
- #define BITMAP_SZ DIV_ROUND_UP(MAX_ADDR_ID + 1, BITS_PER_LONG)
44
-
45
41
struct pm_nl_pernet {
46
42
/* protects pernet updates */
47
43
spinlock_t lock ;
@@ -53,14 +49,14 @@ struct pm_nl_pernet {
53
49
unsigned int local_addr_max ;
54
50
unsigned int subflows_max ;
55
51
unsigned int next_id ;
56
- unsigned long id_bitmap [ BITMAP_SZ ] ;
52
+ DECLARE_BITMAP ( id_bitmap , MPTCP_PM_MAX_ADDR_ID + 1 ) ;
57
53
};
58
54
59
55
#define MPTCP_PM_ADDR_MAX 8
60
56
#define ADD_ADDR_RETRANS_MAX 3
61
57
62
58
static bool addresses_equal (const struct mptcp_addr_info * a ,
63
- struct mptcp_addr_info * b , bool use_port )
59
+ const struct mptcp_addr_info * b , bool use_port )
64
60
{
65
61
bool addr_equals = false;
66
62
@@ -174,6 +170,9 @@ select_local_address(const struct pm_nl_pernet *pernet,
174
170
if (!(entry -> flags & MPTCP_PM_ADDR_FLAG_SUBFLOW ))
175
171
continue ;
176
172
173
+ if (!test_bit (entry -> addr .id , msk -> pm .id_avail_bitmap ))
174
+ continue ;
175
+
177
176
if (entry -> addr .family != sk -> sk_family ) {
178
177
#if IS_ENABLED (CONFIG_MPTCP_IPV6 )
179
178
if ((entry -> addr .family == AF_INET &&
@@ -184,23 +183,17 @@ select_local_address(const struct pm_nl_pernet *pernet,
184
183
continue ;
185
184
}
186
185
187
- /* avoid any address already in use by subflows and
188
- * pending join
189
- */
190
- if (!lookup_subflow_by_saddr (& msk -> conn_list , & entry -> addr )) {
191
- ret = entry ;
192
- break ;
193
- }
186
+ ret = entry ;
187
+ break ;
194
188
}
195
189
rcu_read_unlock ();
196
190
return ret ;
197
191
}
198
192
199
193
static struct mptcp_pm_addr_entry *
200
- select_signal_address (struct pm_nl_pernet * pernet , unsigned int pos )
194
+ select_signal_address (struct pm_nl_pernet * pernet , struct mptcp_sock * msk )
201
195
{
202
196
struct mptcp_pm_addr_entry * entry , * ret = NULL ;
203
- int i = 0 ;
204
197
205
198
rcu_read_lock ();
206
199
/* do not keep any additional per socket state, just signal
@@ -209,12 +202,14 @@ select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos)
209
202
* can lead to additional addresses not being announced.
210
203
*/
211
204
list_for_each_entry_rcu (entry , & pernet -> local_addr_list , list ) {
205
+ if (!test_bit (entry -> addr .id , msk -> pm .id_avail_bitmap ))
206
+ continue ;
207
+
212
208
if (!(entry -> flags & MPTCP_PM_ADDR_FLAG_SIGNAL ))
213
209
continue ;
214
- if (i ++ == pos ) {
215
- ret = entry ;
216
- break ;
217
- }
210
+
211
+ ret = entry ;
212
+ break ;
218
213
}
219
214
rcu_read_unlock ();
220
215
return ret ;
@@ -258,9 +253,11 @@ EXPORT_SYMBOL_GPL(mptcp_pm_get_local_addr_max);
258
253
259
254
static void check_work_pending (struct mptcp_sock * msk )
260
255
{
261
- if (msk -> pm .add_addr_signaled == mptcp_pm_get_add_addr_signal_max (msk ) &&
262
- (msk -> pm .local_addr_used == mptcp_pm_get_local_addr_max (msk ) ||
263
- msk -> pm .subflows == mptcp_pm_get_subflows_max (msk )))
256
+ struct pm_nl_pernet * pernet = net_generic (sock_net ((struct sock * )msk ), pm_nl_pernet_id );
257
+
258
+ if (msk -> pm .subflows == mptcp_pm_get_subflows_max (msk ) ||
259
+ (find_next_and_bit (pernet -> id_bitmap , msk -> pm .id_avail_bitmap ,
260
+ MPTCP_PM_MAX_ADDR_ID + 1 , 0 ) == MPTCP_PM_MAX_ADDR_ID + 1 ))
264
261
WRITE_ONCE (msk -> pm .work_pending , false);
265
262
}
266
263
@@ -460,6 +457,35 @@ static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk, bool fullm
460
457
return i ;
461
458
}
462
459
460
+ static struct mptcp_pm_addr_entry *
461
+ __lookup_addr_by_id (struct pm_nl_pernet * pernet , unsigned int id )
462
+ {
463
+ struct mptcp_pm_addr_entry * entry ;
464
+
465
+ list_for_each_entry (entry , & pernet -> local_addr_list , list ) {
466
+ if (entry -> addr .id == id )
467
+ return entry ;
468
+ }
469
+ return NULL ;
470
+ }
471
+
472
+ static int
473
+ lookup_id_by_addr (struct pm_nl_pernet * pernet , const struct mptcp_addr_info * addr )
474
+ {
475
+ struct mptcp_pm_addr_entry * entry ;
476
+ int ret = -1 ;
477
+
478
+ rcu_read_lock ();
479
+ list_for_each_entry (entry , & pernet -> local_addr_list , list ) {
480
+ if (addresses_equal (& entry -> addr , addr , entry -> addr .port )) {
481
+ ret = entry -> addr .id ;
482
+ break ;
483
+ }
484
+ }
485
+ rcu_read_unlock ();
486
+ return ret ;
487
+ }
488
+
463
489
static void mptcp_pm_create_subflow_or_signal_addr (struct mptcp_sock * msk )
464
490
{
465
491
struct sock * sk = (struct sock * )msk ;
@@ -475,28 +501,36 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
475
501
local_addr_max = mptcp_pm_get_local_addr_max (msk );
476
502
subflows_max = mptcp_pm_get_subflows_max (msk );
477
503
504
+ /* do lazy endpoint usage accounting for the MPC subflows */
505
+ if (unlikely (!(msk -> pm .status & BIT (MPTCP_PM_MPC_ENDPOINT_ACCOUNTED ))) && msk -> first ) {
506
+ struct mptcp_addr_info local ;
507
+ int mpc_id ;
508
+
509
+ local_address ((struct sock_common * )msk -> first , & local );
510
+ mpc_id = lookup_id_by_addr (pernet , & local );
511
+ if (mpc_id < 0 )
512
+ __clear_bit (mpc_id , msk -> pm .id_avail_bitmap );
513
+
514
+ msk -> pm .status |= BIT (MPTCP_PM_MPC_ENDPOINT_ACCOUNTED );
515
+ }
516
+
478
517
pr_debug ("local %d:%d signal %d:%d subflows %d:%d\n" ,
479
518
msk -> pm .local_addr_used , local_addr_max ,
480
519
msk -> pm .add_addr_signaled , add_addr_signal_max ,
481
520
msk -> pm .subflows , subflows_max );
482
521
483
522
/* check first for announce */
484
523
if (msk -> pm .add_addr_signaled < add_addr_signal_max ) {
485
- local = select_signal_address (pernet ,
486
- msk -> pm .add_addr_signaled );
524
+ local = select_signal_address (pernet , msk );
487
525
488
526
if (local ) {
489
527
if (mptcp_pm_alloc_anno_list (msk , local )) {
528
+ __clear_bit (local -> addr .id , msk -> pm .id_avail_bitmap );
490
529
msk -> pm .add_addr_signaled ++ ;
491
530
mptcp_pm_announce_addr (msk , & local -> addr , false);
492
531
mptcp_pm_nl_addr_send_ack (msk );
493
532
}
494
- } else {
495
- /* pick failed, avoid fourther attempts later */
496
- msk -> pm .local_addr_used = add_addr_signal_max ;
497
533
}
498
-
499
- check_work_pending (msk );
500
534
}
501
535
502
536
/* check if should create a new subflow */
@@ -510,19 +544,16 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
510
544
int i , nr ;
511
545
512
546
msk -> pm .local_addr_used ++ ;
513
- check_work_pending (msk );
514
547
nr = fill_remote_addresses_vec (msk , fullmesh , addrs );
548
+ if (nr )
549
+ __clear_bit (local -> addr .id , msk -> pm .id_avail_bitmap );
515
550
spin_unlock_bh (& msk -> pm .lock );
516
551
for (i = 0 ; i < nr ; i ++ )
517
552
__mptcp_subflow_connect (sk , & local -> addr , & addrs [i ]);
518
553
spin_lock_bh (& msk -> pm .lock );
519
- return ;
520
554
}
521
-
522
- /* lookup failed, avoid fourther attempts later */
523
- msk -> pm .local_addr_used = local_addr_max ;
524
- check_work_pending (msk );
525
555
}
556
+ check_work_pending (msk );
526
557
}
527
558
528
559
static void mptcp_pm_nl_fully_established (struct mptcp_sock * msk )
@@ -736,6 +767,7 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
736
767
msk -> pm .subflows -- ;
737
768
__MPTCP_INC_STATS (sock_net (sk ), rm_type );
738
769
}
770
+ __set_bit (rm_list -> ids [1 ], msk -> pm .id_avail_bitmap );
739
771
if (!removed )
740
772
continue ;
741
773
@@ -765,6 +797,9 @@ void mptcp_pm_nl_work(struct mptcp_sock *msk)
765
797
766
798
msk_owned_by_me (msk );
767
799
800
+ if (!(pm -> status & MPTCP_PM_WORK_MASK ))
801
+ return ;
802
+
768
803
spin_lock_bh (& msk -> pm .lock );
769
804
770
805
pr_debug ("msk=%p status=%x" , msk , pm -> status );
@@ -810,7 +845,7 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
810
845
/* to keep the code simple, don't do IDR-like allocation for address ID,
811
846
* just bail when we exceed limits
812
847
*/
813
- if (pernet -> next_id == MAX_ADDR_ID )
848
+ if (pernet -> next_id == MPTCP_PM_MAX_ADDR_ID )
814
849
pernet -> next_id = 1 ;
815
850
if (pernet -> addrs >= MPTCP_PM_ADDR_MAX )
816
851
goto out ;
@@ -830,7 +865,7 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
830
865
if (!entry -> addr .id ) {
831
866
find_next :
832
867
entry -> addr .id = find_next_zero_bit (pernet -> id_bitmap ,
833
- MAX_ADDR_ID + 1 ,
868
+ MPTCP_PM_MAX_ADDR_ID + 1 ,
834
869
pernet -> next_id );
835
870
if (!entry -> addr .id && pernet -> next_id != 1 ) {
836
871
pernet -> next_id = 1 ;
@@ -1197,18 +1232,6 @@ static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
1197
1232
return 0 ;
1198
1233
}
1199
1234
1200
- static struct mptcp_pm_addr_entry *
1201
- __lookup_addr_by_id (struct pm_nl_pernet * pernet , unsigned int id )
1202
- {
1203
- struct mptcp_pm_addr_entry * entry ;
1204
-
1205
- list_for_each_entry (entry , & pernet -> local_addr_list , list ) {
1206
- if (entry -> addr .id == id )
1207
- return entry ;
1208
- }
1209
- return NULL ;
1210
- }
1211
-
1212
1235
int mptcp_pm_get_flags_and_ifindex_by_id (struct net * net , unsigned int id ,
1213
1236
u8 * flags , int * ifindex )
1214
1237
{
@@ -1467,7 +1490,7 @@ static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info)
1467
1490
list_splice_init (& pernet -> local_addr_list , & free_list );
1468
1491
__reset_counters (pernet );
1469
1492
pernet -> next_id = 1 ;
1470
- bitmap_zero (pernet -> id_bitmap , MAX_ADDR_ID + 1 );
1493
+ bitmap_zero (pernet -> id_bitmap , MPTCP_PM_MAX_ADDR_ID + 1 );
1471
1494
spin_unlock_bh (& pernet -> lock );
1472
1495
mptcp_nl_remove_addrs_list (sock_net (skb -> sk ), & free_list );
1473
1496
synchronize_rcu ();
@@ -1577,7 +1600,7 @@ static int mptcp_nl_cmd_dump_addrs(struct sk_buff *msg,
1577
1600
pernet = net_generic (net , pm_nl_pernet_id );
1578
1601
1579
1602
spin_lock_bh (& pernet -> lock );
1580
- for (i = id ; i < MAX_ADDR_ID + 1 ; i ++ ) {
1603
+ for (i = id ; i < MPTCP_PM_MAX_ADDR_ID + 1 ; i ++ ) {
1581
1604
if (test_bit (i , pernet -> id_bitmap )) {
1582
1605
entry = __lookup_addr_by_id (pernet , i );
1583
1606
if (!entry )
0 commit comments