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

Commit e682adf

Browse files
Fan Duklassert
authored andcommitted
xfrm: Try to honor policy index if it's supplied by user
xfrm code always searches for unused policy index for newly created policy regardless whether or not user space policy index hint supplied. This patch enables such feature so that using "ip xfrm ... index=xxx" can be used by user to set specific policy index. Currently this beahvior is broken, so this patch make it happen as expected. Signed-off-by: Fan Du <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent d70f2cf commit e682adf

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

net/xfrm/xfrm_policy.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ static void xfrm_hash_resize(struct work_struct *work)
538538

539539
/* Generate new index... KAME seems to generate them ordered by cost
540540
* of an absolute inpredictability of ordering of rules. This will not pass. */
541-
static u32 xfrm_gen_index(struct net *net, int dir)
541+
static u32 xfrm_gen_index(struct net *net, int dir, u32 index)
542542
{
543543
static u32 idx_generator;
544544

@@ -548,8 +548,14 @@ static u32 xfrm_gen_index(struct net *net, int dir)
548548
u32 idx;
549549
int found;
550550

551-
idx = (idx_generator | dir);
552-
idx_generator += 8;
551+
if (!index) {
552+
idx = (idx_generator | dir);
553+
idx_generator += 8;
554+
} else {
555+
idx = index;
556+
index = 0;
557+
}
558+
553559
if (idx == 0)
554560
idx = 8;
555561
list = net->xfrm.policy_byidx + idx_hash(net, idx);
@@ -672,7 +678,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
672678
xfrm_policy_requeue(delpol, policy);
673679
__xfrm_policy_unlink(delpol, dir);
674680
}
675-
policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir);
681+
policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir, policy->index);
676682
hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index));
677683
policy->curlft.add_time = get_seconds();
678684
policy->curlft.use_time = 0;
@@ -1192,7 +1198,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
11921198
sk->sk_policy[dir] = pol;
11931199
if (pol) {
11941200
pol->curlft.add_time = get_seconds();
1195-
pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir);
1201+
pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir, 0);
11961202
__xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
11971203
}
11981204
if (old_pol) {

net/xfrm/xfrm_user.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,8 @@ static int verify_policy_type(u8 type)
11891189

11901190
static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
11911191
{
1192+
int ret;
1193+
11921194
switch (p->share) {
11931195
case XFRM_SHARE_ANY:
11941196
case XFRM_SHARE_SESSION:
@@ -1224,7 +1226,13 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
12241226
return -EINVAL;
12251227
}
12261228

1227-
return verify_policy_dir(p->dir);
1229+
ret = verify_policy_dir(p->dir);
1230+
if (ret)
1231+
return ret;
1232+
if (p->index && ((p->index & XFRM_POLICY_MAX) != p->dir))
1233+
return -EINVAL;
1234+
1235+
return 0;
12281236
}
12291237

12301238
static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs)

0 commit comments

Comments
 (0)