@@ -36,6 +36,9 @@ struct mptcp_pm_add_entry {
36
36
u8 retrans_times ;
37
37
};
38
38
39
+ #define MAX_ADDR_ID 255
40
+ #define BITMAP_SZ DIV_ROUND_UP(MAX_ADDR_ID + 1, BITS_PER_LONG)
41
+
39
42
struct pm_nl_pernet {
40
43
/* protects pernet updates */
41
44
spinlock_t lock ;
@@ -46,6 +49,7 @@ struct pm_nl_pernet {
46
49
unsigned int local_addr_max ;
47
50
unsigned int subflows_max ;
48
51
unsigned int next_id ;
52
+ unsigned long id_bitmap [BITMAP_SZ ];
49
53
};
50
54
51
55
#define MPTCP_PM_ADDR_MAX 8
@@ -524,10 +528,12 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
524
528
/* to keep the code simple, don't do IDR-like allocation for address ID,
525
529
* just bail when we exceed limits
526
530
*/
527
- if (pernet -> next_id > 255 )
528
- goto out ;
531
+ if (pernet -> next_id == MAX_ADDR_ID )
532
+ pernet -> next_id = 1 ;
529
533
if (pernet -> addrs >= MPTCP_PM_ADDR_MAX )
530
534
goto out ;
535
+ if (test_bit (entry -> addr .id , pernet -> id_bitmap ))
536
+ goto out ;
531
537
532
538
/* do not insert duplicate address, differentiate on port only
533
539
* singled addresses
@@ -539,12 +545,30 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
539
545
goto out ;
540
546
}
541
547
548
+ if (!entry -> addr .id ) {
549
+ find_next :
550
+ entry -> addr .id = find_next_zero_bit (pernet -> id_bitmap ,
551
+ MAX_ADDR_ID + 1 ,
552
+ pernet -> next_id );
553
+ if ((!entry -> addr .id || entry -> addr .id > MAX_ADDR_ID ) &&
554
+ pernet -> next_id != 1 ) {
555
+ pernet -> next_id = 1 ;
556
+ goto find_next ;
557
+ }
558
+ }
559
+
560
+ if (!entry -> addr .id || entry -> addr .id > MAX_ADDR_ID )
561
+ goto out ;
562
+
563
+ __set_bit (entry -> addr .id , pernet -> id_bitmap );
564
+ if (entry -> addr .id > pernet -> next_id )
565
+ pernet -> next_id = entry -> addr .id ;
566
+
542
567
if (entry -> addr .flags & MPTCP_PM_ADDR_FLAG_SIGNAL )
543
568
pernet -> add_addr_signal_max ++ ;
544
569
if (entry -> addr .flags & MPTCP_PM_ADDR_FLAG_SUBFLOW )
545
570
pernet -> local_addr_max ++ ;
546
571
547
- entry -> addr .id = pernet -> next_id ++ ;
548
572
pernet -> addrs ++ ;
549
573
list_add_tail_rcu (& entry -> list , & pernet -> local_addr_list );
550
574
ret = entry -> addr .id ;
@@ -597,6 +621,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
597
621
entry -> addr = skc_local ;
598
622
entry -> addr .ifindex = 0 ;
599
623
entry -> addr .flags = 0 ;
624
+ entry -> addr .id = 0 ;
600
625
ret = mptcp_pm_nl_append_new_local_addr (pernet , entry );
601
626
if (ret < 0 )
602
627
kfree (entry );
@@ -857,6 +882,7 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
857
882
858
883
pernet -> addrs -- ;
859
884
list_del_rcu (& entry -> list );
885
+ __clear_bit (entry -> addr .id , pernet -> id_bitmap );
860
886
spin_unlock_bh (& pernet -> lock );
861
887
862
888
mptcp_nl_remove_subflow_and_signal_addr (sock_net (skb -> sk ), & entry -> addr );
@@ -894,6 +920,8 @@ static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info)
894
920
spin_lock_bh (& pernet -> lock );
895
921
list_splice_init (& pernet -> local_addr_list , & free_list );
896
922
__reset_counters (pernet );
923
+ pernet -> next_id = 1 ;
924
+ bitmap_zero (pernet -> id_bitmap , MAX_ADDR_ID + 1 );
897
925
spin_unlock_bh (& pernet -> lock );
898
926
__flush_addrs (sock_net (skb -> sk ), & free_list );
899
927
return 0 ;
@@ -994,27 +1022,34 @@ static int mptcp_nl_cmd_dump_addrs(struct sk_buff *msg,
994
1022
struct pm_nl_pernet * pernet ;
995
1023
int id = cb -> args [0 ];
996
1024
void * hdr ;
1025
+ int i ;
997
1026
998
1027
pernet = net_generic (net , pm_nl_pernet_id );
999
1028
1000
1029
spin_lock_bh (& pernet -> lock );
1001
- list_for_each_entry (entry , & pernet -> local_addr_list , list ) {
1002
- if (entry -> addr .id <= id )
1003
- continue ;
1004
-
1005
- hdr = genlmsg_put (msg , NETLINK_CB (cb -> skb ).portid ,
1006
- cb -> nlh -> nlmsg_seq , & mptcp_genl_family ,
1007
- NLM_F_MULTI , MPTCP_PM_CMD_GET_ADDR );
1008
- if (!hdr )
1009
- break ;
1030
+ for (i = id ; i < MAX_ADDR_ID + 1 ; i ++ ) {
1031
+ if (test_bit (i , pernet -> id_bitmap )) {
1032
+ entry = __lookup_addr_by_id (pernet , i );
1033
+ if (!entry )
1034
+ break ;
1035
+
1036
+ if (entry -> addr .id <= id )
1037
+ continue ;
1038
+
1039
+ hdr = genlmsg_put (msg , NETLINK_CB (cb -> skb ).portid ,
1040
+ cb -> nlh -> nlmsg_seq , & mptcp_genl_family ,
1041
+ NLM_F_MULTI , MPTCP_PM_CMD_GET_ADDR );
1042
+ if (!hdr )
1043
+ break ;
1044
+
1045
+ if (mptcp_nl_fill_addr (msg , entry ) < 0 ) {
1046
+ genlmsg_cancel (msg , hdr );
1047
+ break ;
1048
+ }
1010
1049
1011
- if (mptcp_nl_fill_addr (msg , entry ) < 0 ) {
1012
- genlmsg_cancel (msg , hdr );
1013
- break ;
1050
+ id = entry -> addr .id ;
1051
+ genlmsg_end (msg , hdr );
1014
1052
}
1015
-
1016
- id = entry -> addr .id ;
1017
- genlmsg_end (msg , hdr );
1018
1053
}
1019
1054
spin_unlock_bh (& pernet -> lock );
1020
1055
@@ -1148,6 +1183,7 @@ static int __net_init pm_nl_init_net(struct net *net)
1148
1183
INIT_LIST_HEAD_RCU (& pernet -> local_addr_list );
1149
1184
__reset_counters (pernet );
1150
1185
pernet -> next_id = 1 ;
1186
+ bitmap_zero (pernet -> id_bitmap , MAX_ADDR_ID + 1 );
1151
1187
spin_lock_init (& pernet -> lock );
1152
1188
return 0 ;
1153
1189
}
0 commit comments