@@ -48,6 +48,7 @@ struct xfrm_flo {
4848
4949struct xfrm_pol_inexact_key {
5050 possible_net_t net ;
51+ u32 if_id ;
5152 u16 family ;
5253 u8 dir , type ;
5354};
@@ -85,11 +86,12 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
8586 int dir );
8687
8788static struct xfrm_pol_inexact_bin *
88- xfrm_policy_inexact_lookup (struct net * net , u8 type , u16 family , u8 dir );
89+ xfrm_policy_inexact_lookup (struct net * net , u8 type , u16 family , u8 dir ,
90+ u32 if_id );
8991
9092static struct xfrm_pol_inexact_bin *
9193xfrm_policy_inexact_lookup_rcu (struct net * net ,
92- u8 type , u16 family , u8 dir );
94+ u8 type , u16 family , u8 dir , u32 if_id );
9395static struct xfrm_policy *
9496xfrm_policy_insert_list (struct hlist_head * chain , struct xfrm_policy * policy ,
9597 bool excl );
@@ -618,6 +620,7 @@ xfrm_policy_inexact_alloc_bin(const struct xfrm_policy *pol, u8 dir)
618620 .family = pol -> family ,
619621 .type = pol -> type ,
620622 .dir = dir ,
623+ .if_id = pol -> if_id ,
621624 };
622625 struct net * net = xp_net (pol );
623626
@@ -925,7 +928,8 @@ static u32 xfrm_pol_bin_key(const void *data, u32 len, u32 seed)
925928 const struct xfrm_pol_inexact_key * k = data ;
926929 u32 a = k -> type << 24 | k -> dir << 16 | k -> family ;
927930
928- return jhash_2words (a , net_hash_mix (read_pnet (& k -> net )), seed );
931+ return jhash_3words (a , k -> if_id , net_hash_mix (read_pnet (& k -> net )),
932+ seed );
929933}
930934
931935static u32 xfrm_pol_bin_obj (const void * data , u32 len , u32 seed )
@@ -957,7 +961,7 @@ static int xfrm_pol_bin_cmp(struct rhashtable_compare_arg *arg,
957961 if (ret )
958962 return ret ;
959963
960- return 0 ;
964+ return b -> k . if_id ^ key -> if_id ;
961965}
962966
963967static const struct rhashtable_params xfrm_pol_inexact_params = {
@@ -1094,7 +1098,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u32 if_id,
10941098 chain = policy_hash_bysel (net , sel , sel -> family , dir );
10951099 if (!chain ) {
10961100 bin = xfrm_policy_inexact_lookup (net , type ,
1097- sel -> family , dir );
1101+ sel -> family , dir , if_id );
10981102 if (!bin ) {
10991103 spin_unlock_bh (& net -> xfrm .xfrm_policy_lock );
11001104 return NULL ;
@@ -1335,12 +1339,14 @@ static int xfrm_policy_match(const struct xfrm_policy *pol,
13351339}
13361340
13371341static struct xfrm_pol_inexact_bin *
1338- xfrm_policy_inexact_lookup_rcu (struct net * net , u8 type , u16 family , u8 dir )
1342+ xfrm_policy_inexact_lookup_rcu (struct net * net , u8 type , u16 family ,
1343+ u8 dir , u32 if_id )
13391344{
13401345 struct xfrm_pol_inexact_key k = {
13411346 .family = family ,
13421347 .type = type ,
13431348 .dir = dir ,
1349+ .if_id = if_id ,
13441350 };
13451351
13461352 write_pnet (& k .net , net );
@@ -1350,14 +1356,15 @@ xfrm_policy_inexact_lookup_rcu(struct net *net, u8 type, u16 family, u8 dir)
13501356}
13511357
13521358static struct xfrm_pol_inexact_bin *
1353- xfrm_policy_inexact_lookup (struct net * net , u8 type , u16 family , u8 dir )
1359+ xfrm_policy_inexact_lookup (struct net * net , u8 type , u16 family ,
1360+ u8 dir , u32 if_id )
13541361{
13551362 struct xfrm_pol_inexact_bin * bin ;
13561363
13571364 lockdep_assert_held (& net -> xfrm .xfrm_policy_lock );
13581365
13591366 rcu_read_lock ();
1360- bin = xfrm_policy_inexact_lookup_rcu (net , type , family , dir );
1367+ bin = xfrm_policy_inexact_lookup_rcu (net , type , family , dir , if_id );
13611368 rcu_read_unlock ();
13621369
13631370 return bin ;
@@ -1405,7 +1412,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type,
14051412 break ;
14061413 }
14071414 }
1408- bin = xfrm_policy_inexact_lookup_rcu (net , type , family , dir );
1415+ bin = xfrm_policy_inexact_lookup_rcu (net , type , family , dir , if_id );
14091416 if (!bin )
14101417 goto skip_inexact ;
14111418 chain = & bin -> hhead ;
0 commit comments