aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorFan Du <fan.du@windriver.com>2013-11-07 04:47:48 -0500
committerSteffen Klassert <steffen.klassert@secunet.com>2013-12-06 00:45:05 -0500
commite682adf021be796940be6cc10c07be7f7398c220 (patch)
tree5dbb9c9ddef2e08945d3bcd73d391b0181bfc9eb /net/xfrm
parentd70f2cf520cf8c86c6b467fc5dcea524ec51dc2f (diff)
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 <fan.du@windriver.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c16
-rw-r--r--net/xfrm/xfrm_user.c10
2 files changed, 20 insertions, 6 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 9a91f7431c41..a5bbdfb2874b 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -538,7 +538,7 @@ static void xfrm_hash_resize(struct work_struct *work)
538 538
539/* Generate new index... KAME seems to generate them ordered by cost 539/* Generate new index... KAME seems to generate them ordered by cost
540 * of an absolute inpredictability of ordering of rules. This will not pass. */ 540 * of an absolute inpredictability of ordering of rules. This will not pass. */
541static u32 xfrm_gen_index(struct net *net, int dir) 541static u32 xfrm_gen_index(struct net *net, int dir, u32 index)
542{ 542{
543 static u32 idx_generator; 543 static u32 idx_generator;
544 544
@@ -548,8 +548,14 @@ static u32 xfrm_gen_index(struct net *net, int dir)
548 u32 idx; 548 u32 idx;
549 int found; 549 int found;
550 550
551 idx = (idx_generator | dir); 551 if (!index) {
552 idx_generator += 8; 552 idx = (idx_generator | dir);
553 idx_generator += 8;
554 } else {
555 idx = index;
556 index = 0;
557 }
558
553 if (idx == 0) 559 if (idx == 0)
554 idx = 8; 560 idx = 8;
555 list = net->xfrm.policy_byidx + idx_hash(net, idx); 561 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)
672 xfrm_policy_requeue(delpol, policy); 678 xfrm_policy_requeue(delpol, policy);
673 __xfrm_policy_unlink(delpol, dir); 679 __xfrm_policy_unlink(delpol, dir);
674 } 680 }
675 policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir); 681 policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir, policy->index);
676 hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index)); 682 hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index));
677 policy->curlft.add_time = get_seconds(); 683 policy->curlft.add_time = get_seconds();
678 policy->curlft.use_time = 0; 684 policy->curlft.use_time = 0;
@@ -1192,7 +1198,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
1192 sk->sk_policy[dir] = pol; 1198 sk->sk_policy[dir] = pol;
1193 if (pol) { 1199 if (pol) {
1194 pol->curlft.add_time = get_seconds(); 1200 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);
1196 __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir); 1202 __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
1197 } 1203 }
1198 if (old_pol) { 1204 if (old_pol) {
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index f964d4c00ffb..4e0546e9bb0a 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1189,6 +1189,8 @@ static int verify_policy_type(u8 type)
1189 1189
1190static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) 1190static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
1191{ 1191{
1192 int ret;
1193
1192 switch (p->share) { 1194 switch (p->share) {
1193 case XFRM_SHARE_ANY: 1195 case XFRM_SHARE_ANY:
1194 case XFRM_SHARE_SESSION: 1196 case XFRM_SHARE_SESSION:
@@ -1224,7 +1226,13 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
1224 return -EINVAL; 1226 return -EINVAL;
1225 } 1227 }
1226 1228
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;
1228} 1236}
1229 1237
1230static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs) 1238static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs)