Skip to content

Commit b5fe22e

Browse files
Florian Westphalklassert
authored andcommitted
xfrm: policy: consider if_id when hashing inexact policy
This avoids searches of polices that cannot match in the first place due to different interface id by placing them in different bins. Signed-off-by: Florian Westphal <[email protected]> Acked-by: David S. Miller <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent 24969fa commit b5fe22e

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

net/xfrm/xfrm_policy.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct xfrm_flo {
4848

4949
struct 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

8788
static 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

9092
static struct xfrm_pol_inexact_bin *
9193
xfrm_policy_inexact_lookup_rcu(struct net *net,
92-
u8 type, u16 family, u8 dir);
94+
u8 type, u16 family, u8 dir, u32 if_id);
9395
static struct xfrm_policy *
9496
xfrm_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

931935
static 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

963967
static 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

13371341
static 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

13521358
static 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

Comments
 (0)