aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_state.c')
-rw-r--r--net/xfrm/xfrm_state.c197
1 files changed, 114 insertions, 83 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 68c2f357a183..a26b7aa79475 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -35,8 +35,6 @@
35 destination/tunnel endpoint. (output) 35 destination/tunnel endpoint. (output)
36 */ 36 */
37 37
38static DEFINE_SPINLOCK(xfrm_state_lock);
39
40static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024; 38static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
41 39
42static inline unsigned int xfrm_dst_hash(struct net *net, 40static inline unsigned int xfrm_dst_hash(struct net *net,
@@ -127,7 +125,7 @@ static void xfrm_hash_resize(struct work_struct *work)
127 goto out_unlock; 125 goto out_unlock;
128 } 126 }
129 127
130 spin_lock_bh(&xfrm_state_lock); 128 spin_lock_bh(&net->xfrm.xfrm_state_lock);
131 129
132 nhashmask = (nsize / sizeof(struct hlist_head)) - 1U; 130 nhashmask = (nsize / sizeof(struct hlist_head)) - 1U;
133 for (i = net->xfrm.state_hmask; i >= 0; i--) 131 for (i = net->xfrm.state_hmask; i >= 0; i--)
@@ -144,7 +142,7 @@ static void xfrm_hash_resize(struct work_struct *work)
144 net->xfrm.state_byspi = nspi; 142 net->xfrm.state_byspi = nspi;
145 net->xfrm.state_hmask = nhashmask; 143 net->xfrm.state_hmask = nhashmask;
146 144
147 spin_unlock_bh(&xfrm_state_lock); 145 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
148 146
149 osize = (ohashmask + 1) * sizeof(struct hlist_head); 147 osize = (ohashmask + 1) * sizeof(struct hlist_head);
150 xfrm_hash_free(odst, osize); 148 xfrm_hash_free(odst, osize);
@@ -374,8 +372,6 @@ static void xfrm_state_gc_task(struct work_struct *work)
374 372
375 hlist_for_each_entry_safe(x, tmp, &gc_list, gclist) 373 hlist_for_each_entry_safe(x, tmp, &gc_list, gclist)
376 xfrm_state_gc_destroy(x); 374 xfrm_state_gc_destroy(x);
377
378 wake_up(&net->xfrm.km_waitq);
379} 375}
380 376
381static inline unsigned long make_jiffies(long secs) 377static inline unsigned long make_jiffies(long secs)
@@ -386,11 +382,10 @@ static inline unsigned long make_jiffies(long secs)
386 return secs*HZ; 382 return secs*HZ;
387} 383}
388 384
389static enum hrtimer_restart xfrm_timer_handler(struct hrtimer * me) 385static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me)
390{ 386{
391 struct tasklet_hrtimer *thr = container_of(me, struct tasklet_hrtimer, timer); 387 struct tasklet_hrtimer *thr = container_of(me, struct tasklet_hrtimer, timer);
392 struct xfrm_state *x = container_of(thr, struct xfrm_state, mtimer); 388 struct xfrm_state *x = container_of(thr, struct xfrm_state, mtimer);
393 struct net *net = xs_net(x);
394 unsigned long now = get_seconds(); 389 unsigned long now = get_seconds();
395 long next = LONG_MAX; 390 long next = LONG_MAX;
396 int warn = 0; 391 int warn = 0;
@@ -453,19 +448,15 @@ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer * me)
453 if (warn) 448 if (warn)
454 km_state_expired(x, 0, 0); 449 km_state_expired(x, 0, 0);
455resched: 450resched:
456 if (next != LONG_MAX){ 451 if (next != LONG_MAX) {
457 tasklet_hrtimer_start(&x->mtimer, ktime_set(next, 0), HRTIMER_MODE_REL); 452 tasklet_hrtimer_start(&x->mtimer, ktime_set(next, 0), HRTIMER_MODE_REL);
458 } 453 }
459 454
460 goto out; 455 goto out;
461 456
462expired: 457expired:
463 if (x->km.state == XFRM_STATE_ACQ && x->id.spi == 0) { 458 if (x->km.state == XFRM_STATE_ACQ && x->id.spi == 0)
464 x->km.state = XFRM_STATE_EXPIRED; 459 x->km.state = XFRM_STATE_EXPIRED;
465 wake_up(&net->xfrm.km_waitq);
466 next = 2;
467 goto resched;
468 }
469 460
470 err = __xfrm_state_delete(x); 461 err = __xfrm_state_delete(x);
471 if (!err) 462 if (!err)
@@ -535,14 +526,14 @@ int __xfrm_state_delete(struct xfrm_state *x)
535 526
536 if (x->km.state != XFRM_STATE_DEAD) { 527 if (x->km.state != XFRM_STATE_DEAD) {
537 x->km.state = XFRM_STATE_DEAD; 528 x->km.state = XFRM_STATE_DEAD;
538 spin_lock(&xfrm_state_lock); 529 spin_lock(&net->xfrm.xfrm_state_lock);
539 list_del(&x->km.all); 530 list_del(&x->km.all);
540 hlist_del(&x->bydst); 531 hlist_del(&x->bydst);
541 hlist_del(&x->bysrc); 532 hlist_del(&x->bysrc);
542 if (x->id.spi) 533 if (x->id.spi)
543 hlist_del(&x->byspi); 534 hlist_del(&x->byspi);
544 net->xfrm.state_num--; 535 net->xfrm.state_num--;
545 spin_unlock(&xfrm_state_lock); 536 spin_unlock(&net->xfrm.xfrm_state_lock);
546 537
547 /* All xfrm_state objects are created by xfrm_state_alloc. 538 /* All xfrm_state objects are created by xfrm_state_alloc.
548 * The xfrm_state_alloc call gives a reference, and that 539 * The xfrm_state_alloc call gives a reference, and that
@@ -603,7 +594,7 @@ int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info)
603{ 594{
604 int i, err = 0, cnt = 0; 595 int i, err = 0, cnt = 0;
605 596
606 spin_lock_bh(&xfrm_state_lock); 597 spin_lock_bh(&net->xfrm.xfrm_state_lock);
607 err = xfrm_state_flush_secctx_check(net, proto, audit_info); 598 err = xfrm_state_flush_secctx_check(net, proto, audit_info);
608 if (err) 599 if (err)
609 goto out; 600 goto out;
@@ -616,7 +607,7 @@ restart:
616 if (!xfrm_state_kern(x) && 607 if (!xfrm_state_kern(x) &&
617 xfrm_id_proto_match(x->id.proto, proto)) { 608 xfrm_id_proto_match(x->id.proto, proto)) {
618 xfrm_state_hold(x); 609 xfrm_state_hold(x);
619 spin_unlock_bh(&xfrm_state_lock); 610 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
620 611
621 err = xfrm_state_delete(x); 612 err = xfrm_state_delete(x);
622 xfrm_audit_state_delete(x, err ? 0 : 1, 613 xfrm_audit_state_delete(x, err ? 0 : 1,
@@ -627,7 +618,7 @@ restart:
627 if (!err) 618 if (!err)
628 cnt++; 619 cnt++;
629 620
630 spin_lock_bh(&xfrm_state_lock); 621 spin_lock_bh(&net->xfrm.xfrm_state_lock);
631 goto restart; 622 goto restart;
632 } 623 }
633 } 624 }
@@ -636,19 +627,18 @@ restart:
636 err = 0; 627 err = 0;
637 628
638out: 629out:
639 spin_unlock_bh(&xfrm_state_lock); 630 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
640 wake_up(&net->xfrm.km_waitq);
641 return err; 631 return err;
642} 632}
643EXPORT_SYMBOL(xfrm_state_flush); 633EXPORT_SYMBOL(xfrm_state_flush);
644 634
645void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si) 635void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si)
646{ 636{
647 spin_lock_bh(&xfrm_state_lock); 637 spin_lock_bh(&net->xfrm.xfrm_state_lock);
648 si->sadcnt = net->xfrm.state_num; 638 si->sadcnt = net->xfrm.state_num;
649 si->sadhcnt = net->xfrm.state_hmask; 639 si->sadhcnt = net->xfrm.state_hmask;
650 si->sadhmcnt = xfrm_state_hashmax; 640 si->sadhmcnt = xfrm_state_hashmax;
651 spin_unlock_bh(&xfrm_state_lock); 641 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
652} 642}
653EXPORT_SYMBOL(xfrm_sad_getinfo); 643EXPORT_SYMBOL(xfrm_sad_getinfo);
654 644
@@ -801,7 +791,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
801 791
802 to_put = NULL; 792 to_put = NULL;
803 793
804 spin_lock_bh(&xfrm_state_lock); 794 spin_lock_bh(&net->xfrm.xfrm_state_lock);
805 h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family); 795 h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family);
806 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) { 796 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
807 if (x->props.family == encap_family && 797 if (x->props.family == encap_family &&
@@ -886,7 +876,7 @@ out:
886 xfrm_state_hold(x); 876 xfrm_state_hold(x);
887 else 877 else
888 *err = acquire_in_progress ? -EAGAIN : error; 878 *err = acquire_in_progress ? -EAGAIN : error;
889 spin_unlock_bh(&xfrm_state_lock); 879 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
890 if (to_put) 880 if (to_put)
891 xfrm_state_put(to_put); 881 xfrm_state_put(to_put);
892 return x; 882 return x;
@@ -900,7 +890,7 @@ xfrm_stateonly_find(struct net *net, u32 mark,
900 unsigned int h; 890 unsigned int h;
901 struct xfrm_state *rx = NULL, *x = NULL; 891 struct xfrm_state *rx = NULL, *x = NULL;
902 892
903 spin_lock(&xfrm_state_lock); 893 spin_lock_bh(&net->xfrm.xfrm_state_lock);
904 h = xfrm_dst_hash(net, daddr, saddr, reqid, family); 894 h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
905 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) { 895 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
906 if (x->props.family == family && 896 if (x->props.family == family &&
@@ -918,13 +908,35 @@ xfrm_stateonly_find(struct net *net, u32 mark,
918 908
919 if (rx) 909 if (rx)
920 xfrm_state_hold(rx); 910 xfrm_state_hold(rx);
921 spin_unlock(&xfrm_state_lock); 911 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
922 912
923 913
924 return rx; 914 return rx;
925} 915}
926EXPORT_SYMBOL(xfrm_stateonly_find); 916EXPORT_SYMBOL(xfrm_stateonly_find);
927 917
918struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
919 unsigned short family)
920{
921 struct xfrm_state *x;
922 struct xfrm_state_walk *w;
923
924 spin_lock_bh(&net->xfrm.xfrm_state_lock);
925 list_for_each_entry(w, &net->xfrm.state_all, all) {
926 x = container_of(w, struct xfrm_state, km);
927 if (x->props.family != family ||
928 x->id.spi != spi)
929 continue;
930
931 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
932 xfrm_state_hold(x);
933 return x;
934 }
935 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
936 return NULL;
937}
938EXPORT_SYMBOL(xfrm_state_lookup_byspi);
939
928static void __xfrm_state_insert(struct xfrm_state *x) 940static void __xfrm_state_insert(struct xfrm_state *x)
929{ 941{
930 struct net *net = xs_net(x); 942 struct net *net = xs_net(x);
@@ -950,14 +962,12 @@ static void __xfrm_state_insert(struct xfrm_state *x)
950 if (x->replay_maxage) 962 if (x->replay_maxage)
951 mod_timer(&x->rtimer, jiffies + x->replay_maxage); 963 mod_timer(&x->rtimer, jiffies + x->replay_maxage);
952 964
953 wake_up(&net->xfrm.km_waitq);
954
955 net->xfrm.state_num++; 965 net->xfrm.state_num++;
956 966
957 xfrm_hash_grow_check(net, x->bydst.next != NULL); 967 xfrm_hash_grow_check(net, x->bydst.next != NULL);
958} 968}
959 969
960/* xfrm_state_lock is held */ 970/* net->xfrm.xfrm_state_lock is held */
961static void __xfrm_state_bump_genids(struct xfrm_state *xnew) 971static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
962{ 972{
963 struct net *net = xs_net(xnew); 973 struct net *net = xs_net(xnew);
@@ -980,14 +990,16 @@ static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
980 990
981void xfrm_state_insert(struct xfrm_state *x) 991void xfrm_state_insert(struct xfrm_state *x)
982{ 992{
983 spin_lock_bh(&xfrm_state_lock); 993 struct net *net = xs_net(x);
994
995 spin_lock_bh(&net->xfrm.xfrm_state_lock);
984 __xfrm_state_bump_genids(x); 996 __xfrm_state_bump_genids(x);
985 __xfrm_state_insert(x); 997 __xfrm_state_insert(x);
986 spin_unlock_bh(&xfrm_state_lock); 998 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
987} 999}
988EXPORT_SYMBOL(xfrm_state_insert); 1000EXPORT_SYMBOL(xfrm_state_insert);
989 1001
990/* xfrm_state_lock is held */ 1002/* net->xfrm.xfrm_state_lock is held */
991static struct xfrm_state *__find_acq_core(struct net *net, 1003static struct xfrm_state *__find_acq_core(struct net *net,
992 const struct xfrm_mark *m, 1004 const struct xfrm_mark *m,
993 unsigned short family, u8 mode, 1005 unsigned short family, u8 mode,
@@ -1079,7 +1091,7 @@ int xfrm_state_add(struct xfrm_state *x)
1079 1091
1080 to_put = NULL; 1092 to_put = NULL;
1081 1093
1082 spin_lock_bh(&xfrm_state_lock); 1094 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1083 1095
1084 x1 = __xfrm_state_locate(x, use_spi, family); 1096 x1 = __xfrm_state_locate(x, use_spi, family);
1085 if (x1) { 1097 if (x1) {
@@ -1108,7 +1120,7 @@ int xfrm_state_add(struct xfrm_state *x)
1108 err = 0; 1120 err = 0;
1109 1121
1110out: 1122out:
1111 spin_unlock_bh(&xfrm_state_lock); 1123 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1112 1124
1113 if (x1) { 1125 if (x1) {
1114 xfrm_state_delete(x1); 1126 xfrm_state_delete(x1);
@@ -1203,16 +1215,16 @@ out:
1203 return NULL; 1215 return NULL;
1204} 1216}
1205 1217
1206/* xfrm_state_lock is held */ 1218/* net->xfrm.xfrm_state_lock is held */
1207struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m) 1219struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net)
1208{ 1220{
1209 unsigned int h; 1221 unsigned int h;
1210 struct xfrm_state *x; 1222 struct xfrm_state *x;
1211 1223
1212 if (m->reqid) { 1224 if (m->reqid) {
1213 h = xfrm_dst_hash(&init_net, &m->old_daddr, &m->old_saddr, 1225 h = xfrm_dst_hash(net, &m->old_daddr, &m->old_saddr,
1214 m->reqid, m->old_family); 1226 m->reqid, m->old_family);
1215 hlist_for_each_entry(x, init_net.xfrm.state_bydst+h, bydst) { 1227 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
1216 if (x->props.mode != m->mode || 1228 if (x->props.mode != m->mode ||
1217 x->id.proto != m->proto) 1229 x->id.proto != m->proto)
1218 continue; 1230 continue;
@@ -1227,9 +1239,9 @@ struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
1227 return x; 1239 return x;
1228 } 1240 }
1229 } else { 1241 } else {
1230 h = xfrm_src_hash(&init_net, &m->old_daddr, &m->old_saddr, 1242 h = xfrm_src_hash(net, &m->old_daddr, &m->old_saddr,
1231 m->old_family); 1243 m->old_family);
1232 hlist_for_each_entry(x, init_net.xfrm.state_bysrc+h, bysrc) { 1244 hlist_for_each_entry(x, net->xfrm.state_bysrc+h, bysrc) {
1233 if (x->props.mode != m->mode || 1245 if (x->props.mode != m->mode ||
1234 x->id.proto != m->proto) 1246 x->id.proto != m->proto)
1235 continue; 1247 continue;
@@ -1247,8 +1259,8 @@ struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
1247} 1259}
1248EXPORT_SYMBOL(xfrm_migrate_state_find); 1260EXPORT_SYMBOL(xfrm_migrate_state_find);
1249 1261
1250struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x, 1262struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
1251 struct xfrm_migrate *m) 1263 struct xfrm_migrate *m)
1252{ 1264{
1253 struct xfrm_state *xc; 1265 struct xfrm_state *xc;
1254 int err; 1266 int err;
@@ -1283,10 +1295,11 @@ int xfrm_state_update(struct xfrm_state *x)
1283 struct xfrm_state *x1, *to_put; 1295 struct xfrm_state *x1, *to_put;
1284 int err; 1296 int err;
1285 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY); 1297 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
1298 struct net *net = xs_net(x);
1286 1299
1287 to_put = NULL; 1300 to_put = NULL;
1288 1301
1289 spin_lock_bh(&xfrm_state_lock); 1302 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1290 x1 = __xfrm_state_locate(x, use_spi, x->props.family); 1303 x1 = __xfrm_state_locate(x, use_spi, x->props.family);
1291 1304
1292 err = -ESRCH; 1305 err = -ESRCH;
@@ -1306,7 +1319,7 @@ int xfrm_state_update(struct xfrm_state *x)
1306 err = 0; 1319 err = 0;
1307 1320
1308out: 1321out:
1309 spin_unlock_bh(&xfrm_state_lock); 1322 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1310 1323
1311 if (to_put) 1324 if (to_put)
1312 xfrm_state_put(to_put); 1325 xfrm_state_put(to_put);
@@ -1357,7 +1370,7 @@ int xfrm_state_check_expire(struct xfrm_state *x)
1357 if (x->curlft.bytes >= x->lft.hard_byte_limit || 1370 if (x->curlft.bytes >= x->lft.hard_byte_limit ||
1358 x->curlft.packets >= x->lft.hard_packet_limit) { 1371 x->curlft.packets >= x->lft.hard_packet_limit) {
1359 x->km.state = XFRM_STATE_EXPIRED; 1372 x->km.state = XFRM_STATE_EXPIRED;
1360 tasklet_hrtimer_start(&x->mtimer, ktime_set(0,0), HRTIMER_MODE_REL); 1373 tasklet_hrtimer_start(&x->mtimer, ktime_set(0, 0), HRTIMER_MODE_REL);
1361 return -EINVAL; 1374 return -EINVAL;
1362 } 1375 }
1363 1376
@@ -1377,9 +1390,9 @@ xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32
1377{ 1390{
1378 struct xfrm_state *x; 1391 struct xfrm_state *x;
1379 1392
1380 spin_lock_bh(&xfrm_state_lock); 1393 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1381 x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family); 1394 x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family);
1382 spin_unlock_bh(&xfrm_state_lock); 1395 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1383 return x; 1396 return x;
1384} 1397}
1385EXPORT_SYMBOL(xfrm_state_lookup); 1398EXPORT_SYMBOL(xfrm_state_lookup);
@@ -1391,9 +1404,9 @@ xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1391{ 1404{
1392 struct xfrm_state *x; 1405 struct xfrm_state *x;
1393 1406
1394 spin_lock_bh(&xfrm_state_lock); 1407 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1395 x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family); 1408 x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family);
1396 spin_unlock_bh(&xfrm_state_lock); 1409 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1397 return x; 1410 return x;
1398} 1411}
1399EXPORT_SYMBOL(xfrm_state_lookup_byaddr); 1412EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
@@ -1405,9 +1418,9 @@ xfrm_find_acq(struct net *net, const struct xfrm_mark *mark, u8 mode, u32 reqid,
1405{ 1418{
1406 struct xfrm_state *x; 1419 struct xfrm_state *x;
1407 1420
1408 spin_lock_bh(&xfrm_state_lock); 1421 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1409 x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create); 1422 x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create);
1410 spin_unlock_bh(&xfrm_state_lock); 1423 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1411 1424
1412 return x; 1425 return x;
1413} 1426}
@@ -1416,17 +1429,17 @@ EXPORT_SYMBOL(xfrm_find_acq);
1416#ifdef CONFIG_XFRM_SUB_POLICY 1429#ifdef CONFIG_XFRM_SUB_POLICY
1417int 1430int
1418xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, 1431xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
1419 unsigned short family) 1432 unsigned short family, struct net *net)
1420{ 1433{
1421 int err = 0; 1434 int err = 0;
1422 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); 1435 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
1423 if (!afinfo) 1436 if (!afinfo)
1424 return -EAFNOSUPPORT; 1437 return -EAFNOSUPPORT;
1425 1438
1426 spin_lock_bh(&xfrm_state_lock); 1439 spin_lock_bh(&net->xfrm.xfrm_state_lock); /*FIXME*/
1427 if (afinfo->tmpl_sort) 1440 if (afinfo->tmpl_sort)
1428 err = afinfo->tmpl_sort(dst, src, n); 1441 err = afinfo->tmpl_sort(dst, src, n);
1429 spin_unlock_bh(&xfrm_state_lock); 1442 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1430 xfrm_state_put_afinfo(afinfo); 1443 xfrm_state_put_afinfo(afinfo);
1431 return err; 1444 return err;
1432} 1445}
@@ -1438,13 +1451,15 @@ xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1438{ 1451{
1439 int err = 0; 1452 int err = 0;
1440 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); 1453 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
1454 struct net *net = xs_net(*dst);
1455
1441 if (!afinfo) 1456 if (!afinfo)
1442 return -EAFNOSUPPORT; 1457 return -EAFNOSUPPORT;
1443 1458
1444 spin_lock_bh(&xfrm_state_lock); 1459 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1445 if (afinfo->state_sort) 1460 if (afinfo->state_sort)
1446 err = afinfo->state_sort(dst, src, n); 1461 err = afinfo->state_sort(dst, src, n);
1447 spin_unlock_bh(&xfrm_state_lock); 1462 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1448 xfrm_state_put_afinfo(afinfo); 1463 xfrm_state_put_afinfo(afinfo);
1449 return err; 1464 return err;
1450} 1465}
@@ -1476,9 +1491,9 @@ struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
1476{ 1491{
1477 struct xfrm_state *x; 1492 struct xfrm_state *x;
1478 1493
1479 spin_lock_bh(&xfrm_state_lock); 1494 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1480 x = __xfrm_find_acq_byseq(net, mark, seq); 1495 x = __xfrm_find_acq_byseq(net, mark, seq);
1481 spin_unlock_bh(&xfrm_state_lock); 1496 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1482 return x; 1497 return x;
1483} 1498}
1484EXPORT_SYMBOL(xfrm_find_acq_byseq); 1499EXPORT_SYMBOL(xfrm_find_acq_byseq);
@@ -1496,6 +1511,30 @@ u32 xfrm_get_acqseq(void)
1496} 1511}
1497EXPORT_SYMBOL(xfrm_get_acqseq); 1512EXPORT_SYMBOL(xfrm_get_acqseq);
1498 1513
1514int verify_spi_info(u8 proto, u32 min, u32 max)
1515{
1516 switch (proto) {
1517 case IPPROTO_AH:
1518 case IPPROTO_ESP:
1519 break;
1520
1521 case IPPROTO_COMP:
1522 /* IPCOMP spi is 16-bits. */
1523 if (max >= 0x10000)
1524 return -EINVAL;
1525 break;
1526
1527 default:
1528 return -EINVAL;
1529 }
1530
1531 if (min > max)
1532 return -EINVAL;
1533
1534 return 0;
1535}
1536EXPORT_SYMBOL(verify_spi_info);
1537
1499int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) 1538int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
1500{ 1539{
1501 struct net *net = xs_net(x); 1540 struct net *net = xs_net(x);
@@ -1525,8 +1564,8 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
1525 x->id.spi = minspi; 1564 x->id.spi = minspi;
1526 } else { 1565 } else {
1527 u32 spi = 0; 1566 u32 spi = 0;
1528 for (h=0; h<high-low+1; h++) { 1567 for (h = 0; h < high-low+1; h++) {
1529 spi = low + net_random()%(high-low+1); 1568 spi = low + prandom_u32()%(high-low+1);
1530 x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family); 1569 x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
1531 if (x0 == NULL) { 1570 if (x0 == NULL) {
1532 x->id.spi = htonl(spi); 1571 x->id.spi = htonl(spi);
@@ -1536,10 +1575,10 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
1536 } 1575 }
1537 } 1576 }
1538 if (x->id.spi) { 1577 if (x->id.spi) {
1539 spin_lock_bh(&xfrm_state_lock); 1578 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1540 h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family); 1579 h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family);
1541 hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); 1580 hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
1542 spin_unlock_bh(&xfrm_state_lock); 1581 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1543 1582
1544 err = 0; 1583 err = 0;
1545 } 1584 }
@@ -1562,7 +1601,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1562 if (walk->seq != 0 && list_empty(&walk->all)) 1601 if (walk->seq != 0 && list_empty(&walk->all))
1563 return 0; 1602 return 0;
1564 1603
1565 spin_lock_bh(&xfrm_state_lock); 1604 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1566 if (list_empty(&walk->all)) 1605 if (list_empty(&walk->all))
1567 x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all); 1606 x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all);
1568 else 1607 else
@@ -1586,7 +1625,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1586 } 1625 }
1587 list_del_init(&walk->all); 1626 list_del_init(&walk->all);
1588out: 1627out:
1589 spin_unlock_bh(&xfrm_state_lock); 1628 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1590 return err; 1629 return err;
1591} 1630}
1592EXPORT_SYMBOL(xfrm_state_walk); 1631EXPORT_SYMBOL(xfrm_state_walk);
@@ -1600,20 +1639,20 @@ void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
1600} 1639}
1601EXPORT_SYMBOL(xfrm_state_walk_init); 1640EXPORT_SYMBOL(xfrm_state_walk_init);
1602 1641
1603void xfrm_state_walk_done(struct xfrm_state_walk *walk) 1642void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net)
1604{ 1643{
1605 if (list_empty(&walk->all)) 1644 if (list_empty(&walk->all))
1606 return; 1645 return;
1607 1646
1608 spin_lock_bh(&xfrm_state_lock); 1647 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1609 list_del(&walk->all); 1648 list_del(&walk->all);
1610 spin_unlock_bh(&xfrm_state_lock); 1649 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1611} 1650}
1612EXPORT_SYMBOL(xfrm_state_walk_done); 1651EXPORT_SYMBOL(xfrm_state_walk_done);
1613 1652
1614static void xfrm_replay_timer_handler(unsigned long data) 1653static void xfrm_replay_timer_handler(unsigned long data)
1615{ 1654{
1616 struct xfrm_state *x = (struct xfrm_state*)data; 1655 struct xfrm_state *x = (struct xfrm_state *)data;
1617 1656
1618 spin_lock(&x->lock); 1657 spin_lock(&x->lock);
1619 1658
@@ -1655,16 +1694,12 @@ EXPORT_SYMBOL(km_state_notify);
1655 1694
1656void km_state_expired(struct xfrm_state *x, int hard, u32 portid) 1695void km_state_expired(struct xfrm_state *x, int hard, u32 portid)
1657{ 1696{
1658 struct net *net = xs_net(x);
1659 struct km_event c; 1697 struct km_event c;
1660 1698
1661 c.data.hard = hard; 1699 c.data.hard = hard;
1662 c.portid = portid; 1700 c.portid = portid;
1663 c.event = XFRM_MSG_EXPIRE; 1701 c.event = XFRM_MSG_EXPIRE;
1664 km_state_notify(x, &c); 1702 km_state_notify(x, &c);
1665
1666 if (hard)
1667 wake_up(&net->xfrm.km_waitq);
1668} 1703}
1669 1704
1670EXPORT_SYMBOL(km_state_expired); 1705EXPORT_SYMBOL(km_state_expired);
@@ -1707,16 +1742,12 @@ EXPORT_SYMBOL(km_new_mapping);
1707 1742
1708void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid) 1743void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid)
1709{ 1744{
1710 struct net *net = xp_net(pol);
1711 struct km_event c; 1745 struct km_event c;
1712 1746
1713 c.data.hard = hard; 1747 c.data.hard = hard;
1714 c.portid = portid; 1748 c.portid = portid;
1715 c.event = XFRM_MSG_POLEXPIRE; 1749 c.event = XFRM_MSG_POLEXPIRE;
1716 km_policy_notify(pol, dir, &c); 1750 km_policy_notify(pol, dir, &c);
1717
1718 if (hard)
1719 wake_up(&net->xfrm.km_waitq);
1720} 1751}
1721EXPORT_SYMBOL(km_policy_expired); 1752EXPORT_SYMBOL(km_policy_expired);
1722 1753
@@ -2025,7 +2056,7 @@ int __net_init xfrm_state_init(struct net *net)
2025 INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize); 2056 INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize);
2026 INIT_HLIST_HEAD(&net->xfrm.state_gc_list); 2057 INIT_HLIST_HEAD(&net->xfrm.state_gc_list);
2027 INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task); 2058 INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task);
2028 init_waitqueue_head(&net->xfrm.km_waitq); 2059 spin_lock_init(&net->xfrm.xfrm_state_lock);
2029 return 0; 2060 return 0;
2030 2061
2031out_byspi: 2062out_byspi:
@@ -2043,7 +2074,7 @@ void xfrm_state_fini(struct net *net)
2043 2074
2044 flush_work(&net->xfrm.state_hash_work); 2075 flush_work(&net->xfrm.state_hash_work);
2045 audit_info.loginuid = INVALID_UID; 2076 audit_info.loginuid = INVALID_UID;
2046 audit_info.sessionid = -1; 2077 audit_info.sessionid = (unsigned int)-1;
2047 audit_info.secid = 0; 2078 audit_info.secid = 0;
2048 xfrm_state_flush(net, IPSEC_PROTO_ANY, &audit_info); 2079 xfrm_state_flush(net, IPSEC_PROTO_ANY, &audit_info);
2049 flush_work(&net->xfrm.state_gc_work); 2080 flush_work(&net->xfrm.state_gc_work);
@@ -2070,7 +2101,7 @@ static void xfrm_audit_helper_sainfo(struct xfrm_state *x,
2070 audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s", 2101 audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
2071 ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str); 2102 ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
2072 2103
2073 switch(x->props.family) { 2104 switch (x->props.family) {
2074 case AF_INET: 2105 case AF_INET:
2075 audit_log_format(audit_buf, " src=%pI4 dst=%pI4", 2106 audit_log_format(audit_buf, " src=%pI4 dst=%pI4",
2076 &x->props.saddr.a4, &x->id.daddr.a4); 2107 &x->props.saddr.a4, &x->id.daddr.a4);
@@ -2100,7 +2131,7 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
2100 iph6 = ipv6_hdr(skb); 2131 iph6 = ipv6_hdr(skb);
2101 audit_log_format(audit_buf, 2132 audit_log_format(audit_buf,
2102 " src=%pI6 dst=%pI6 flowlbl=0x%x%02x%02x", 2133 " src=%pI6 dst=%pI6 flowlbl=0x%x%02x%02x",
2103 &iph6->saddr,&iph6->daddr, 2134 &iph6->saddr, &iph6->daddr,
2104 iph6->flow_lbl[0] & 0x0f, 2135 iph6->flow_lbl[0] & 0x0f,
2105 iph6->flow_lbl[1], 2136 iph6->flow_lbl[1],
2106 iph6->flow_lbl[2]); 2137 iph6->flow_lbl[2]);
@@ -2109,7 +2140,7 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
2109} 2140}
2110 2141
2111void xfrm_audit_state_add(struct xfrm_state *x, int result, 2142void xfrm_audit_state_add(struct xfrm_state *x, int result,
2112 kuid_t auid, u32 sessionid, u32 secid) 2143 kuid_t auid, unsigned int sessionid, u32 secid)
2113{ 2144{
2114 struct audit_buffer *audit_buf; 2145 struct audit_buffer *audit_buf;
2115 2146
@@ -2124,7 +2155,7 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result,
2124EXPORT_SYMBOL_GPL(xfrm_audit_state_add); 2155EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
2125 2156
2126void xfrm_audit_state_delete(struct xfrm_state *x, int result, 2157void xfrm_audit_state_delete(struct xfrm_state *x, int result,
2127 kuid_t auid, u32 sessionid, u32 secid) 2158 kuid_t auid, unsigned int sessionid, u32 secid)
2128{ 2159{
2129 struct audit_buffer *audit_buf; 2160 struct audit_buffer *audit_buf;
2130 2161