@@ -1257,13 +1257,10 @@ static void xfrm_hash_rebuild(struct work_struct *work)
1257
1257
{
1258
1258
struct net * net = container_of (work , struct net ,
1259
1259
xfrm .policy_hthresh .work );
1260
- unsigned int hmask ;
1261
1260
struct xfrm_policy * pol ;
1262
1261
struct xfrm_policy * policy ;
1263
1262
struct hlist_head * chain ;
1264
- struct hlist_head * odst ;
1265
1263
struct hlist_node * newpos ;
1266
- int i ;
1267
1264
int dir ;
1268
1265
unsigned seq ;
1269
1266
u8 lbits4 , rbits4 , lbits6 , rbits6 ;
@@ -1324,23 +1321,7 @@ static void xfrm_hash_rebuild(struct work_struct *work)
1324
1321
goto out_unlock ;
1325
1322
}
1326
1323
1327
- /* reset the bydst and inexact table in all directions */
1328
1324
for (dir = 0 ; dir < XFRM_POLICY_MAX ; dir ++ ) {
1329
- struct hlist_node * n ;
1330
-
1331
- hlist_for_each_entry_safe (policy , n ,
1332
- & net -> xfrm .policy_inexact [dir ],
1333
- bydst_inexact_list ) {
1334
- hlist_del_rcu (& policy -> bydst );
1335
- hlist_del_init (& policy -> bydst_inexact_list );
1336
- }
1337
-
1338
- hmask = net -> xfrm .policy_bydst [dir ].hmask ;
1339
- odst = net -> xfrm .policy_bydst [dir ].table ;
1340
- for (i = hmask ; i >= 0 ; i -- ) {
1341
- hlist_for_each_entry_safe (policy , n , odst + i , bydst )
1342
- hlist_del_rcu (& policy -> bydst );
1343
- }
1344
1325
if ((dir & XFRM_POLICY_MASK ) == XFRM_POLICY_OUT ) {
1345
1326
/* dir out => dst = remote, src = local */
1346
1327
net -> xfrm .policy_bydst [dir ].dbits4 = rbits4 ;
@@ -4486,63 +4467,50 @@ EXPORT_SYMBOL_GPL(xfrm_audit_policy_delete);
4486
4467
#endif
4487
4468
4488
4469
#ifdef CONFIG_XFRM_MIGRATE
4489
- static bool xfrm_migrate_selector_match (const struct xfrm_selector * sel_cmp ,
4490
- const struct xfrm_selector * sel_tgt )
4491
- {
4492
- if (sel_cmp -> proto == IPSEC_ULPROTO_ANY ) {
4493
- if (sel_tgt -> family == sel_cmp -> family &&
4494
- xfrm_addr_equal (& sel_tgt -> daddr , & sel_cmp -> daddr ,
4495
- sel_cmp -> family ) &&
4496
- xfrm_addr_equal (& sel_tgt -> saddr , & sel_cmp -> saddr ,
4497
- sel_cmp -> family ) &&
4498
- sel_tgt -> prefixlen_d == sel_cmp -> prefixlen_d &&
4499
- sel_tgt -> prefixlen_s == sel_cmp -> prefixlen_s ) {
4500
- return true;
4501
- }
4502
- } else {
4503
- if (memcmp (sel_tgt , sel_cmp , sizeof (* sel_tgt )) == 0 ) {
4504
- return true;
4505
- }
4506
- }
4507
- return false;
4508
- }
4509
-
4510
4470
static struct xfrm_policy * xfrm_migrate_policy_find (const struct xfrm_selector * sel ,
4511
4471
u8 dir , u8 type , struct net * net , u32 if_id )
4512
4472
{
4513
- struct xfrm_policy * pol , * ret = NULL ;
4514
- struct hlist_head * chain ;
4515
- u32 priority = ~0U ;
4473
+ struct xfrm_policy * pol ;
4474
+ struct flowi fl ;
4516
4475
4517
- spin_lock_bh (& net -> xfrm .xfrm_policy_lock );
4518
- chain = policy_hash_direct (net , & sel -> daddr , & sel -> saddr , sel -> family , dir );
4519
- hlist_for_each_entry (pol , chain , bydst ) {
4520
- if ((if_id == 0 || pol -> if_id == if_id ) &&
4521
- xfrm_migrate_selector_match (sel , & pol -> selector ) &&
4522
- pol -> type == type ) {
4523
- ret = pol ;
4524
- priority = ret -> priority ;
4525
- break ;
4526
- }
4527
- }
4528
- chain = & net -> xfrm .policy_inexact [dir ];
4529
- hlist_for_each_entry (pol , chain , bydst_inexact_list ) {
4530
- if ((pol -> priority >= priority ) && ret )
4531
- break ;
4476
+ memset (& fl , 0 , sizeof (fl ));
4532
4477
4533
- if ((if_id == 0 || pol -> if_id == if_id ) &&
4534
- xfrm_migrate_selector_match (sel , & pol -> selector ) &&
4535
- pol -> type == type ) {
4536
- ret = pol ;
4478
+ fl .flowi_proto = sel -> proto ;
4479
+
4480
+ switch (sel -> family ) {
4481
+ case AF_INET :
4482
+ fl .u .ip4 .saddr = sel -> saddr .a4 ;
4483
+ fl .u .ip4 .daddr = sel -> daddr .a4 ;
4484
+ if (sel -> proto == IPSEC_ULPROTO_ANY )
4537
4485
break ;
4538
- }
4486
+ fl .u .flowi4_oif = sel -> ifindex ;
4487
+ fl .u .ip4 .fl4_sport = sel -> sport ;
4488
+ fl .u .ip4 .fl4_dport = sel -> dport ;
4489
+ break ;
4490
+ case AF_INET6 :
4491
+ fl .u .ip6 .saddr = sel -> saddr .in6 ;
4492
+ fl .u .ip6 .daddr = sel -> daddr .in6 ;
4493
+ if (sel -> proto == IPSEC_ULPROTO_ANY )
4494
+ break ;
4495
+ fl .u .flowi6_oif = sel -> ifindex ;
4496
+ fl .u .ip6 .fl4_sport = sel -> sport ;
4497
+ fl .u .ip6 .fl4_dport = sel -> dport ;
4498
+ break ;
4499
+ default :
4500
+ return ERR_PTR (- EAFNOSUPPORT );
4539
4501
}
4540
4502
4541
- xfrm_pol_hold ( ret );
4503
+ rcu_read_lock ( );
4542
4504
4543
- spin_unlock_bh (& net -> xfrm .xfrm_policy_lock );
4505
+ pol = xfrm_policy_lookup_bytype (net , type , & fl , sel -> family , dir , if_id );
4506
+ if (IS_ERR_OR_NULL (pol ))
4507
+ goto out_unlock ;
4544
4508
4545
- return ret ;
4509
+ if (!xfrm_pol_hold_rcu (pol ))
4510
+ pol = NULL ;
4511
+ out_unlock :
4512
+ rcu_read_unlock ();
4513
+ return pol ;
4546
4514
}
4547
4515
4548
4516
static int migrate_tmpl_match (const struct xfrm_migrate * m , const struct xfrm_tmpl * t )
@@ -4679,9 +4647,9 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
4679
4647
4680
4648
/* Stage 1 - find policy */
4681
4649
pol = xfrm_migrate_policy_find (sel , dir , type , net , if_id );
4682
- if (! pol ) {
4650
+ if (IS_ERR_OR_NULL ( pol ) ) {
4683
4651
NL_SET_ERR_MSG (extack , "Target policy not found" );
4684
- err = - ENOENT ;
4652
+ err = IS_ERR ( pol ) ? PTR_ERR ( pol ) : - ENOENT ;
4685
4653
goto out ;
4686
4654
}
4687
4655
0 commit comments