From 8f3ee7fd7dc34b54e9c063ef3c2c0765a652d1de Mon Sep 17 00:00:00 2001 From: Terence Tritton Date: Thu, 19 Sep 2024 09:56:15 +0000 Subject: [PATCH] Revert "xfrm: policy: remove remaining use of inexact list" This reverts commit a54ad727f74559f7c3dfcfd2a63d0ce7683a82e8. Bug: 367633876 Signed-off-by: Terence Tritton Change-Id: Id872891910aa24816d4e73f4b7b32b1064ebacab --- include/net/xfrm.h | 1 + net/xfrm/xfrm_policy.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index f62088bc813b..661a28536e61 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -585,6 +585,7 @@ struct xfrm_policy { u16 family; struct xfrm_sec_ctx *security; struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; + struct hlist_node bydst_inexact_list; struct rcu_head rcu; struct xfrm_dev_offload xdo; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 914bac03b52a..66d1ec71869f 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -201,6 +201,8 @@ xfrm_policy_inexact_lookup_rcu(struct net *net, static struct xfrm_policy * xfrm_policy_insert_list(struct hlist_head *chain, struct xfrm_policy *policy, bool excl); +static void xfrm_policy_insert_inexact_list(struct hlist_head *chain, + struct xfrm_policy *policy); static bool xfrm_policy_find_inexact_candidates(struct xfrm_pol_inexact_candidates *cand, @@ -413,6 +415,7 @@ struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp) if (policy) { write_pnet(&policy->xp_net, net); INIT_LIST_HEAD(&policy->walk.all); + INIT_HLIST_NODE(&policy->bydst_inexact_list); INIT_HLIST_NODE(&policy->bydst); INIT_HLIST_NODE(&policy->byidx); rwlock_init(&policy->lock); @@ -1230,6 +1233,9 @@ xfrm_policy_inexact_insert(struct xfrm_policy *policy, u8 dir, int excl) return ERR_PTR(-EEXIST); } + chain = &net->xfrm.policy_inexact[dir]; + xfrm_policy_insert_inexact_list(chain, policy); + if (delpol) __xfrm_policy_inexact_prune_bin(bin, false); @@ -1337,6 +1343,7 @@ static void xfrm_hash_rebuild(struct work_struct *work) continue; hlist_del_rcu(&policy->bydst); + hlist_del_init(&policy->bydst_inexact_list); newpos = NULL; dir = xfrm_policy_id2dir(policy->index); @@ -1506,6 +1513,36 @@ static const struct rhashtable_params xfrm_pol_inexact_params = { .automatic_shrinking = true, }; +static void xfrm_policy_insert_inexact_list(struct hlist_head *chain, + struct xfrm_policy *policy) +{ + struct xfrm_policy *pol, *delpol = NULL; + struct hlist_node *newpos = NULL; + + hlist_for_each_entry(pol, chain, bydst_inexact_list) { + if (pol->type == policy->type && + pol->if_id == policy->if_id && + !selector_cmp(&pol->selector, &policy->selector) && + xfrm_policy_mark_match(&policy->mark, pol) && + xfrm_sec_ctx_match(pol->security, policy->security) && + !WARN_ON(delpol)) { + delpol = pol; + if (policy->priority > pol->priority) + continue; + } else if (policy->priority >= pol->priority) { + newpos = &pol->bydst_inexact_list; + continue; + } + if (delpol) + break; + } + + if (newpos && policy->xdo.type != XFRM_DEV_OFFLOAD_PACKET) + hlist_add_behind_rcu(&policy->bydst_inexact_list, newpos); + else + hlist_add_head_rcu(&policy->bydst_inexact_list, chain); +} + static struct xfrm_policy *xfrm_policy_insert_list(struct hlist_head *chain, struct xfrm_policy *policy, bool excl) @@ -2307,6 +2344,7 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, /* Socket policies are not hashed. */ if (!hlist_unhashed(&pol->bydst)) { hlist_del_rcu(&pol->bydst); + hlist_del_init(&pol->bydst_inexact_list); hlist_del(&pol->byidx); }