aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-12-08 21:30:21 -0500
committerDavid S. Miller <davem@davemloft.net>2014-12-08 21:30:21 -0500
commit6db70e3e1d988005c9ae6cf0f023e3c653628efb (patch)
tree696620aaa6ca94caa627dc18617a164af4fdad29 /net/xfrm
parentf5f04bcf539b2cf896929dc00b82010df78045bf (diff)
parentfbe68ee87522f6eaa10f9076c0a7117e1613f2f7 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next
Steffen Klassert says: ==================== pull request (net-next): ipsec-next 2014-12-03 1) Fix a set but not used warning. From Fabian Frederick. 2) Currently we make sequence number values available to userspace only if we use ESN. Make the sequence number values also available for non ESN states. From Zhi Ding. 3) Remove socket policy hashing. We don't need it because socket policies are always looked up via a linked list. From Herbert Xu. 4) After removing socket policy hashing, we can use __xfrm_policy_link in xfrm_policy_insert. From Herbert Xu. 5) Add a lookup method for vti6 tunnels with wildcard endpoints. I forgot this when I initially implemented vti6. Please pull or let me know if there are problems. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c52
-rw-r--r--net/xfrm/xfrm_user.c12
2 files changed, 37 insertions, 27 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 88bf289abdc9..cee479bc655c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -55,6 +55,7 @@ static int stale_bundle(struct dst_entry *dst);
55static int xfrm_bundle_ok(struct xfrm_dst *xdst); 55static int xfrm_bundle_ok(struct xfrm_dst *xdst);
56static void xfrm_policy_queue_process(unsigned long arg); 56static void xfrm_policy_queue_process(unsigned long arg);
57 57
58static void __xfrm_policy_link(struct xfrm_policy *pol, int dir);
58static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, 59static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
59 int dir); 60 int dir);
60 61
@@ -561,7 +562,7 @@ static void xfrm_hash_resize(struct work_struct *work)
561 mutex_lock(&hash_resize_mutex); 562 mutex_lock(&hash_resize_mutex);
562 563
563 total = 0; 564 total = 0;
564 for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) { 565 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
565 if (xfrm_bydst_should_resize(net, dir, &total)) 566 if (xfrm_bydst_should_resize(net, dir, &total))
566 xfrm_bydst_resize(net, dir); 567 xfrm_bydst_resize(net, dir);
567 } 568 }
@@ -601,7 +602,7 @@ static void xfrm_hash_rebuild(struct work_struct *work)
601 write_lock_bh(&net->xfrm.xfrm_policy_lock); 602 write_lock_bh(&net->xfrm.xfrm_policy_lock);
602 603
603 /* reset the bydst and inexact table in all directions */ 604 /* reset the bydst and inexact table in all directions */
604 for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) { 605 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
605 INIT_HLIST_HEAD(&net->xfrm.policy_inexact[dir]); 606 INIT_HLIST_HEAD(&net->xfrm.policy_inexact[dir]);
606 hmask = net->xfrm.policy_bydst[dir].hmask; 607 hmask = net->xfrm.policy_bydst[dir].hmask;
607 odst = net->xfrm.policy_bydst[dir].table; 608 odst = net->xfrm.policy_bydst[dir].table;
@@ -779,8 +780,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
779 hlist_add_behind(&policy->bydst, newpos); 780 hlist_add_behind(&policy->bydst, newpos);
780 else 781 else
781 hlist_add_head(&policy->bydst, chain); 782 hlist_add_head(&policy->bydst, chain);
782 xfrm_pol_hold(policy); 783 __xfrm_policy_link(policy, dir);
783 net->xfrm.policy_count[dir]++;
784 atomic_inc(&net->xfrm.flow_cache_genid); 784 atomic_inc(&net->xfrm.flow_cache_genid);
785 785
786 /* After previous checking, family can either be AF_INET or AF_INET6 */ 786 /* After previous checking, family can either be AF_INET or AF_INET6 */
@@ -799,7 +799,6 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
799 policy->curlft.use_time = 0; 799 policy->curlft.use_time = 0;
800 if (!mod_timer(&policy->timer, jiffies + HZ)) 800 if (!mod_timer(&policy->timer, jiffies + HZ))
801 xfrm_pol_hold(policy); 801 xfrm_pol_hold(policy);
802 list_add(&policy->walk.all, &net->xfrm.policy_all);
803 write_unlock_bh(&net->xfrm.xfrm_policy_lock); 802 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
804 803
805 if (delpol) 804 if (delpol)
@@ -1247,17 +1246,10 @@ out:
1247static void __xfrm_policy_link(struct xfrm_policy *pol, int dir) 1246static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
1248{ 1247{
1249 struct net *net = xp_net(pol); 1248 struct net *net = xp_net(pol);
1250 struct hlist_head *chain = policy_hash_bysel(net, &pol->selector,
1251 pol->family, dir);
1252 1249
1253 list_add(&pol->walk.all, &net->xfrm.policy_all); 1250 list_add(&pol->walk.all, &net->xfrm.policy_all);
1254 hlist_add_head(&pol->bydst, chain);
1255 hlist_add_head(&pol->byidx, net->xfrm.policy_byidx+idx_hash(net, pol->index));
1256 net->xfrm.policy_count[dir]++; 1251 net->xfrm.policy_count[dir]++;
1257 xfrm_pol_hold(pol); 1252 xfrm_pol_hold(pol);
1258
1259 if (xfrm_bydst_should_resize(net, dir, NULL))
1260 schedule_work(&net->xfrm.policy_hash_work);
1261} 1253}
1262 1254
1263static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, 1255static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
@@ -1265,17 +1257,31 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
1265{ 1257{
1266 struct net *net = xp_net(pol); 1258 struct net *net = xp_net(pol);
1267 1259
1268 if (hlist_unhashed(&pol->bydst)) 1260 if (list_empty(&pol->walk.all))
1269 return NULL; 1261 return NULL;
1270 1262
1271 hlist_del_init(&pol->bydst); 1263 /* Socket policies are not hashed. */
1272 hlist_del(&pol->byidx); 1264 if (!hlist_unhashed(&pol->bydst)) {
1273 list_del(&pol->walk.all); 1265 hlist_del(&pol->bydst);
1266 hlist_del(&pol->byidx);
1267 }
1268
1269 list_del_init(&pol->walk.all);
1274 net->xfrm.policy_count[dir]--; 1270 net->xfrm.policy_count[dir]--;
1275 1271
1276 return pol; 1272 return pol;
1277} 1273}
1278 1274
1275static void xfrm_sk_policy_link(struct xfrm_policy *pol, int dir)
1276{
1277 __xfrm_policy_link(pol, XFRM_POLICY_MAX + dir);
1278}
1279
1280static void xfrm_sk_policy_unlink(struct xfrm_policy *pol, int dir)
1281{
1282 __xfrm_policy_unlink(pol, XFRM_POLICY_MAX + dir);
1283}
1284
1279int xfrm_policy_delete(struct xfrm_policy *pol, int dir) 1285int xfrm_policy_delete(struct xfrm_policy *pol, int dir)
1280{ 1286{
1281 struct net *net = xp_net(pol); 1287 struct net *net = xp_net(pol);
@@ -1307,7 +1313,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
1307 if (pol) { 1313 if (pol) {
1308 pol->curlft.add_time = get_seconds(); 1314 pol->curlft.add_time = get_seconds();
1309 pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir, 0); 1315 pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir, 0);
1310 __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir); 1316 xfrm_sk_policy_link(pol, dir);
1311 } 1317 }
1312 if (old_pol) { 1318 if (old_pol) {
1313 if (pol) 1319 if (pol)
@@ -1316,7 +1322,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
1316 /* Unlinking succeeds always. This is the only function 1322 /* Unlinking succeeds always. This is the only function
1317 * allowed to delete or replace socket policy. 1323 * allowed to delete or replace socket policy.
1318 */ 1324 */
1319 __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir); 1325 xfrm_sk_policy_unlink(old_pol, dir);
1320 } 1326 }
1321 write_unlock_bh(&net->xfrm.xfrm_policy_lock); 1327 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
1322 1328
@@ -1349,7 +1355,7 @@ static struct xfrm_policy *clone_policy(const struct xfrm_policy *old, int dir)
1349 memcpy(newp->xfrm_vec, old->xfrm_vec, 1355 memcpy(newp->xfrm_vec, old->xfrm_vec,
1350 newp->xfrm_nr*sizeof(struct xfrm_tmpl)); 1356 newp->xfrm_nr*sizeof(struct xfrm_tmpl));
1351 write_lock_bh(&net->xfrm.xfrm_policy_lock); 1357 write_lock_bh(&net->xfrm.xfrm_policy_lock);
1352 __xfrm_policy_link(newp, XFRM_POLICY_MAX+dir); 1358 xfrm_sk_policy_link(newp, dir);
1353 write_unlock_bh(&net->xfrm.xfrm_policy_lock); 1359 write_unlock_bh(&net->xfrm.xfrm_policy_lock);
1354 xfrm_pol_put(newp); 1360 xfrm_pol_put(newp);
1355 } 1361 }
@@ -1878,7 +1884,6 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
1878 1884
1879static void xfrm_policy_queue_process(unsigned long arg) 1885static void xfrm_policy_queue_process(unsigned long arg)
1880{ 1886{
1881 int err = 0;
1882 struct sk_buff *skb; 1887 struct sk_buff *skb;
1883 struct sock *sk; 1888 struct sock *sk;
1884 struct dst_entry *dst; 1889 struct dst_entry *dst;
@@ -1941,7 +1946,7 @@ static void xfrm_policy_queue_process(unsigned long arg)
1941 skb_dst_drop(skb); 1946 skb_dst_drop(skb);
1942 skb_dst_set(skb, dst); 1947 skb_dst_set(skb, dst);
1943 1948
1944 err = dst_output(skb); 1949 dst_output(skb);
1945 } 1950 }
1946 1951
1947out: 1952out:
@@ -2966,10 +2971,11 @@ static int __net_init xfrm_policy_init(struct net *net)
2966 goto out_byidx; 2971 goto out_byidx;
2967 net->xfrm.policy_idx_hmask = hmask; 2972 net->xfrm.policy_idx_hmask = hmask;
2968 2973
2969 for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) { 2974 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
2970 struct xfrm_policy_hash *htab; 2975 struct xfrm_policy_hash *htab;
2971 2976
2972 net->xfrm.policy_count[dir] = 0; 2977 net->xfrm.policy_count[dir] = 0;
2978 net->xfrm.policy_count[XFRM_POLICY_MAX + dir] = 0;
2973 INIT_HLIST_HEAD(&net->xfrm.policy_inexact[dir]); 2979 INIT_HLIST_HEAD(&net->xfrm.policy_inexact[dir]);
2974 2980
2975 htab = &net->xfrm.policy_bydst[dir]; 2981 htab = &net->xfrm.policy_bydst[dir];
@@ -3021,7 +3027,7 @@ static void xfrm_policy_fini(struct net *net)
3021 3027
3022 WARN_ON(!list_empty(&net->xfrm.policy_all)); 3028 WARN_ON(!list_empty(&net->xfrm.policy_all));
3023 3029
3024 for (dir = 0; dir < XFRM_POLICY_MAX * 2; dir++) { 3030 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
3025 struct xfrm_policy_hash *htab; 3031 struct xfrm_policy_hash *htab;
3026 3032
3027 WARN_ON(!hlist_empty(&net->xfrm.policy_inexact[dir])); 3033 WARN_ON(!hlist_empty(&net->xfrm.policy_inexact[dir]));
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index e812e988c111..8128594ab379 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -824,13 +824,15 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
824 ret = xfrm_mark_put(skb, &x->mark); 824 ret = xfrm_mark_put(skb, &x->mark);
825 if (ret) 825 if (ret)
826 goto out; 826 goto out;
827 if (x->replay_esn) { 827 if (x->replay_esn)
828 ret = nla_put(skb, XFRMA_REPLAY_ESN_VAL, 828 ret = nla_put(skb, XFRMA_REPLAY_ESN_VAL,
829 xfrm_replay_state_esn_len(x->replay_esn), 829 xfrm_replay_state_esn_len(x->replay_esn),
830 x->replay_esn); 830 x->replay_esn);
831 if (ret) 831 else
832 goto out; 832 ret = nla_put(skb, XFRMA_REPLAY_VAL, sizeof(x->replay),
833 } 833 &x->replay);
834 if (ret)
835 goto out;
834 if (x->security) 836 if (x->security)
835 ret = copy_sec_ctx(x->security, skb); 837 ret = copy_sec_ctx(x->security, skb);
836out: 838out:
@@ -2569,6 +2571,8 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x)
2569 l += nla_total_size(sizeof(x->tfcpad)); 2571 l += nla_total_size(sizeof(x->tfcpad));
2570 if (x->replay_esn) 2572 if (x->replay_esn)
2571 l += nla_total_size(xfrm_replay_state_esn_len(x->replay_esn)); 2573 l += nla_total_size(xfrm_replay_state_esn_len(x->replay_esn));
2574 else
2575 l += nla_total_size(sizeof(struct xfrm_replay_state));
2572 if (x->security) 2576 if (x->security)
2573 l += nla_total_size(sizeof(struct xfrm_user_sec_ctx) + 2577 l += nla_total_size(sizeof(struct xfrm_user_sec_ctx) +
2574 x->security->ctx_len); 2578 x->security->ctx_len);