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

Commit 3e20564

Browse files
Terence Trittonlag-google
authored andcommitted
Revert "xfrm: switch migrate to xfrm_policy_lookup_bytype"
This reverts commit 563d5ca. Bug: 367633876 Signed-off-by: Terence Tritton <[email protected]> Change-Id: Ib9fe7365c56dab3f7f99f12a48d5d14e3fbf06ae
1 parent 8f3ee7f commit 3e20564

File tree

1 file changed

+68
-36
lines changed

1 file changed

+68
-36
lines changed

net/xfrm/xfrm_policy.c

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,10 +1257,13 @@ static void xfrm_hash_rebuild(struct work_struct *work)
12571257
{
12581258
struct net *net = container_of(work, struct net,
12591259
xfrm.policy_hthresh.work);
1260+
unsigned int hmask;
12601261
struct xfrm_policy *pol;
12611262
struct xfrm_policy *policy;
12621263
struct hlist_head *chain;
1264+
struct hlist_head *odst;
12631265
struct hlist_node *newpos;
1266+
int i;
12641267
int dir;
12651268
unsigned seq;
12661269
u8 lbits4, rbits4, lbits6, rbits6;
@@ -1321,7 +1324,23 @@ static void xfrm_hash_rebuild(struct work_struct *work)
13211324
goto out_unlock;
13221325
}
13231326

1327+
/* reset the bydst and inexact table in all directions */
13241328
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+
}
13251344
if ((dir & XFRM_POLICY_MASK) == XFRM_POLICY_OUT) {
13261345
/* dir out => dst = remote, src = local */
13271346
net->xfrm.policy_bydst[dir].dbits4 = rbits4;
@@ -4467,50 +4486,63 @@ EXPORT_SYMBOL_GPL(xfrm_audit_policy_delete);
44674486
#endif
44684487

44694488
#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+
44704510
static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *sel,
44714511
u8 dir, u8 type, struct net *net, u32 if_id)
44724512
{
4473-
struct xfrm_policy *pol;
4474-
struct flowi fl;
4475-
4476-
memset(&fl, 0, sizeof(fl));
4477-
4478-
fl.flowi_proto = sel->proto;
4513+
struct xfrm_policy *pol, *ret = NULL;
4514+
struct hlist_head *chain;
4515+
u32 priority = ~0U;
44794516

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)
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;
44854525
break;
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)
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)
44944531
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);
4532+
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;
4537+
break;
4538+
}
45014539
}
45024540

4503-
rcu_read_lock();
4541+
xfrm_pol_hold(ret);
45044542

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;
4543+
spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
45084544

4509-
if (!xfrm_pol_hold_rcu(pol))
4510-
pol = NULL;
4511-
out_unlock:
4512-
rcu_read_unlock();
4513-
return pol;
4545+
return ret;
45144546
}
45154547

45164548
static int migrate_tmpl_match(const struct xfrm_migrate *m, const struct xfrm_tmpl *t)
@@ -4647,9 +4679,9 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
46474679

46484680
/* Stage 1 - find policy */
46494681
pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id);
4650-
if (IS_ERR_OR_NULL(pol)) {
4682+
if (!pol) {
46514683
NL_SET_ERR_MSG(extack, "Target policy not found");
4652-
err = IS_ERR(pol) ? PTR_ERR(pol) : -ENOENT;
4684+
err = -ENOENT;
46534685
goto out;
46544686
}
46554687

0 commit comments

Comments
 (0)