Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 563d5ca

Browse files
Florian Westphalklassert
authored andcommitted
xfrm: switch migrate to xfrm_policy_lookup_bytype
XFRM_MIGRATE still uses the old lookup method: first check the bydst hash table, then search the list of all the other policies. Switch MIGRATE to use the same lookup function as the packetpath. This is done to remove the last remaining users of the pernet xfrm.policy_inexact lists with the intent of removing this list. After this patch, policies are still added to the list on insertion and they are rehashed as-needed but no single API makes use of these anymore. This change is compile tested only. Cc: Tobias Brunner <[email protected]> Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent 33f611c commit 563d5ca

File tree

1 file changed

+39
-67
lines changed

1 file changed

+39
-67
lines changed

net/xfrm/xfrm_policy.c

Lines changed: 39 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,13 +1252,10 @@ static void xfrm_hash_rebuild(struct work_struct *work)
12521252
{
12531253
struct net *net = container_of(work, struct net,
12541254
xfrm.policy_hthresh.work);
1255-
unsigned int hmask;
12561255
struct xfrm_policy *pol;
12571256
struct xfrm_policy *policy;
12581257
struct hlist_head *chain;
1259-
struct hlist_head *odst;
12601258
struct hlist_node *newpos;
1261-
int i;
12621259
int dir;
12631260
unsigned seq;
12641261
u8 lbits4, rbits4, lbits6, rbits6;
@@ -1322,23 +1319,7 @@ static void xfrm_hash_rebuild(struct work_struct *work)
13221319
goto out_unlock;
13231320
}
13241321

1325-
/* reset the bydst and inexact table in all directions */
13261322
for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
1327-
struct hlist_node *n;
1328-
1329-
hlist_for_each_entry_safe(policy, n,
1330-
&net->xfrm.policy_inexact[dir],
1331-
bydst_inexact_list) {
1332-
hlist_del_rcu(&policy->bydst);
1333-
hlist_del_init(&policy->bydst_inexact_list);
1334-
}
1335-
1336-
hmask = net->xfrm.policy_bydst[dir].hmask;
1337-
odst = net->xfrm.policy_bydst[dir].table;
1338-
for (i = hmask; i >= 0; i--) {
1339-
hlist_for_each_entry_safe(policy, n, odst + i, bydst)
1340-
hlist_del_rcu(&policy->bydst);
1341-
}
13421323
if ((dir & XFRM_POLICY_MASK) == XFRM_POLICY_OUT) {
13431324
/* dir out => dst = remote, src = local */
13441325
net->xfrm.policy_bydst[dir].dbits4 = rbits4;
@@ -1363,6 +1344,10 @@ static void xfrm_hash_rebuild(struct work_struct *work)
13631344
/* skip socket policies */
13641345
continue;
13651346
}
1347+
1348+
hlist_del_rcu(&policy->bydst);
1349+
hlist_del_init(&policy->bydst_inexact_list);
1350+
13661351
newpos = NULL;
13671352
chain = policy_hash_bysel(net, &policy->selector,
13681353
policy->family, dir);
@@ -4484,63 +4469,50 @@ EXPORT_SYMBOL_GPL(xfrm_audit_policy_delete);
44844469
#endif
44854470

44864471
#ifdef CONFIG_XFRM_MIGRATE
4487-
static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp,
4488-
const struct xfrm_selector *sel_tgt)
4489-
{
4490-
if (sel_cmp->proto == IPSEC_ULPROTO_ANY) {
4491-
if (sel_tgt->family == sel_cmp->family &&
4492-
xfrm_addr_equal(&sel_tgt->daddr, &sel_cmp->daddr,
4493-
sel_cmp->family) &&
4494-
xfrm_addr_equal(&sel_tgt->saddr, &sel_cmp->saddr,
4495-
sel_cmp->family) &&
4496-
sel_tgt->prefixlen_d == sel_cmp->prefixlen_d &&
4497-
sel_tgt->prefixlen_s == sel_cmp->prefixlen_s) {
4498-
return true;
4499-
}
4500-
} else {
4501-
if (memcmp(sel_tgt, sel_cmp, sizeof(*sel_tgt)) == 0) {
4502-
return true;
4503-
}
4504-
}
4505-
return false;
4506-
}
4507-
45084472
static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *sel,
45094473
u8 dir, u8 type, struct net *net, u32 if_id)
45104474
{
45114475
struct xfrm_policy *pol, *ret = NULL;
4512-
struct hlist_head *chain;
4513-
u32 priority = ~0U;
4476+
struct flowi fl;
45144477

4515-
spin_lock_bh(&net->xfrm.xfrm_policy_lock);
4516-
chain = policy_hash_direct(net, &sel->daddr, &sel->saddr, sel->family, dir);
4517-
hlist_for_each_entry(pol, chain, bydst) {
4518-
if ((if_id == 0 || pol->if_id == if_id) &&
4519-
xfrm_migrate_selector_match(sel, &pol->selector) &&
4520-
pol->type == type) {
4521-
ret = pol;
4522-
priority = ret->priority;
4523-
break;
4524-
}
4525-
}
4526-
chain = &net->xfrm.policy_inexact[dir];
4527-
hlist_for_each_entry(pol, chain, bydst_inexact_list) {
4528-
if ((pol->priority >= priority) && ret)
4529-
break;
4478+
memset(&fl, 0, sizeof(fl));
45304479

4531-
if ((if_id == 0 || pol->if_id == if_id) &&
4532-
xfrm_migrate_selector_match(sel, &pol->selector) &&
4533-
pol->type == type) {
4534-
ret = pol;
4480+
fl.flowi_proto = sel->proto;
4481+
4482+
switch (sel->family) {
4483+
case AF_INET:
4484+
fl.u.ip4.saddr = sel->saddr.a4;
4485+
fl.u.ip4.daddr = sel->daddr.a4;
4486+
if (sel->proto == IPSEC_ULPROTO_ANY)
45354487
break;
4536-
}
4488+
fl.u.flowi4_oif = sel->ifindex;
4489+
fl.u.ip4.fl4_sport = sel->sport;
4490+
fl.u.ip4.fl4_dport = sel->dport;
4491+
break;
4492+
case AF_INET6:
4493+
fl.u.ip6.saddr = sel->saddr.in6;
4494+
fl.u.ip6.daddr = sel->daddr.in6;
4495+
if (sel->proto == IPSEC_ULPROTO_ANY)
4496+
break;
4497+
fl.u.flowi6_oif = sel->ifindex;
4498+
fl.u.ip6.fl4_sport = sel->sport;
4499+
fl.u.ip6.fl4_dport = sel->dport;
4500+
break;
4501+
default:
4502+
return ERR_PTR(-EAFNOSUPPORT);
45374503
}
45384504

4539-
xfrm_pol_hold(ret);
4505+
rcu_read_lock();
45404506

4541-
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
4507+
pol = xfrm_policy_lookup_bytype(net, type, &fl, sel->family, dir, if_id);
4508+
if (IS_ERR_OR_NULL(pol))
4509+
goto out_unlock;
45424510

4543-
return ret;
4511+
if (!xfrm_pol_hold_rcu(ret))
4512+
pol = NULL;
4513+
out_unlock:
4514+
rcu_read_unlock();
4515+
return pol;
45444516
}
45454517

45464518
static int migrate_tmpl_match(const struct xfrm_migrate *m, const struct xfrm_tmpl *t)
@@ -4677,9 +4649,9 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
46774649

46784650
/* Stage 1 - find policy */
46794651
pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id);
4680-
if (!pol) {
4652+
if (IS_ERR_OR_NULL(pol)) {
46814653
NL_SET_ERR_MSG(extack, "Target policy not found");
4682-
err = -ENOENT;
4654+
err = IS_ERR(pol) ? PTR_ERR(pol) : -ENOENT;
46834655
goto out;
46844656
}
46854657

0 commit comments

Comments
 (0)