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.c149
1 files changed, 79 insertions, 70 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 68c2f357a183..a62c25ea3631 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)
@@ -390,7 +386,6 @@ static 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;
@@ -460,12 +455,8 @@ resched:
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(&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,7 +908,7 @@ 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(&net->xfrm.xfrm_state_lock);
922 912
923 913
924 return rx; 914 return rx;
@@ -950,14 +940,12 @@ static void __xfrm_state_insert(struct xfrm_state *x)
950 if (x->replay_maxage) 940 if (x->replay_maxage)
951 mod_timer(&x->rtimer, jiffies + x->replay_maxage); 941 mod_timer(&x->rtimer, jiffies + x->replay_maxage);
952 942
953 wake_up(&net->xfrm.km_waitq);
954
955 net->xfrm.state_num++; 943 net->xfrm.state_num++;
956 944
957 xfrm_hash_grow_check(net, x->bydst.next != NULL); 945 xfrm_hash_grow_check(net, x->bydst.next != NULL);
958} 946}
959 947
960/* xfrm_state_lock is held */ 948/* net->xfrm.xfrm_state_lock is held */
961static void __xfrm_state_bump_genids(struct xfrm_state *xnew) 949static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
962{ 950{
963 struct net *net = xs_net(xnew); 951 struct net *net = xs_net(xnew);
@@ -980,14 +968,16 @@ static void __xfrm_state_bump_genids(struct xfrm_state *xnew)
980 968
981void xfrm_state_insert(struct xfrm_state *x) 969void xfrm_state_insert(struct xfrm_state *x)
982{ 970{
983 spin_lock_bh(&xfrm_state_lock); 971 struct net *net = xs_net(x);
972
973 spin_lock_bh(&net->xfrm.xfrm_state_lock);
984 __xfrm_state_bump_genids(x); 974 __xfrm_state_bump_genids(x);
985 __xfrm_state_insert(x); 975 __xfrm_state_insert(x);
986 spin_unlock_bh(&xfrm_state_lock); 976 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
987} 977}
988EXPORT_SYMBOL(xfrm_state_insert); 978EXPORT_SYMBOL(xfrm_state_insert);
989 979
990/* xfrm_state_lock is held */ 980/* net->xfrm.xfrm_state_lock is held */
991static struct xfrm_state *__find_acq_core(struct net *net, 981static struct xfrm_state *__find_acq_core(struct net *net,
992 const struct xfrm_mark *m, 982 const struct xfrm_mark *m,
993 unsigned short family, u8 mode, 983 unsigned short family, u8 mode,
@@ -1079,7 +1069,7 @@ int xfrm_state_add(struct xfrm_state *x)
1079 1069
1080 to_put = NULL; 1070 to_put = NULL;
1081 1071
1082 spin_lock_bh(&xfrm_state_lock); 1072 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1083 1073
1084 x1 = __xfrm_state_locate(x, use_spi, family); 1074 x1 = __xfrm_state_locate(x, use_spi, family);
1085 if (x1) { 1075 if (x1) {
@@ -1108,7 +1098,7 @@ int xfrm_state_add(struct xfrm_state *x)
1108 err = 0; 1098 err = 0;
1109 1099
1110out: 1100out:
1111 spin_unlock_bh(&xfrm_state_lock); 1101 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1112 1102
1113 if (x1) { 1103 if (x1) {
1114 xfrm_state_delete(x1); 1104 xfrm_state_delete(x1);
@@ -1203,16 +1193,16 @@ out:
1203 return NULL; 1193 return NULL;
1204} 1194}
1205 1195
1206/* xfrm_state_lock is held */ 1196/* net->xfrm.xfrm_state_lock is held */
1207struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m) 1197struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net)
1208{ 1198{
1209 unsigned int h; 1199 unsigned int h;
1210 struct xfrm_state *x; 1200 struct xfrm_state *x;
1211 1201
1212 if (m->reqid) { 1202 if (m->reqid) {
1213 h = xfrm_dst_hash(&init_net, &m->old_daddr, &m->old_saddr, 1203 h = xfrm_dst_hash(net, &m->old_daddr, &m->old_saddr,
1214 m->reqid, m->old_family); 1204 m->reqid, m->old_family);
1215 hlist_for_each_entry(x, init_net.xfrm.state_bydst+h, bydst) { 1205 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
1216 if (x->props.mode != m->mode || 1206 if (x->props.mode != m->mode ||
1217 x->id.proto != m->proto) 1207 x->id.proto != m->proto)
1218 continue; 1208 continue;
@@ -1227,9 +1217,9 @@ struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
1227 return x; 1217 return x;
1228 } 1218 }
1229 } else { 1219 } else {
1230 h = xfrm_src_hash(&init_net, &m->old_daddr, &m->old_saddr, 1220 h = xfrm_src_hash(net, &m->old_daddr, &m->old_saddr,
1231 m->old_family); 1221 m->old_family);
1232 hlist_for_each_entry(x, init_net.xfrm.state_bysrc+h, bysrc) { 1222 hlist_for_each_entry(x, net->xfrm.state_bysrc+h, bysrc) {
1233 if (x->props.mode != m->mode || 1223 if (x->props.mode != m->mode ||
1234 x->id.proto != m->proto) 1224 x->id.proto != m->proto)
1235 continue; 1225 continue;
@@ -1283,10 +1273,11 @@ int xfrm_state_update(struct xfrm_state *x)
1283 struct xfrm_state *x1, *to_put; 1273 struct xfrm_state *x1, *to_put;
1284 int err; 1274 int err;
1285 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY); 1275 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
1276 struct net *net = xs_net(x);
1286 1277
1287 to_put = NULL; 1278 to_put = NULL;
1288 1279
1289 spin_lock_bh(&xfrm_state_lock); 1280 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1290 x1 = __xfrm_state_locate(x, use_spi, x->props.family); 1281 x1 = __xfrm_state_locate(x, use_spi, x->props.family);
1291 1282
1292 err = -ESRCH; 1283 err = -ESRCH;
@@ -1306,7 +1297,7 @@ int xfrm_state_update(struct xfrm_state *x)
1306 err = 0; 1297 err = 0;
1307 1298
1308out: 1299out:
1309 spin_unlock_bh(&xfrm_state_lock); 1300 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1310 1301
1311 if (to_put) 1302 if (to_put)
1312 xfrm_state_put(to_put); 1303 xfrm_state_put(to_put);
@@ -1377,9 +1368,9 @@ xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32
1377{ 1368{
1378 struct xfrm_state *x; 1369 struct xfrm_state *x;
1379 1370
1380 spin_lock_bh(&xfrm_state_lock); 1371 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1381 x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family); 1372 x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family);
1382 spin_unlock_bh(&xfrm_state_lock); 1373 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1383 return x; 1374 return x;
1384} 1375}
1385EXPORT_SYMBOL(xfrm_state_lookup); 1376EXPORT_SYMBOL(xfrm_state_lookup);
@@ -1391,9 +1382,9 @@ xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1391{ 1382{
1392 struct xfrm_state *x; 1383 struct xfrm_state *x;
1393 1384
1394 spin_lock_bh(&xfrm_state_lock); 1385 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1395 x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family); 1386 x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family);
1396 spin_unlock_bh(&xfrm_state_lock); 1387 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1397 return x; 1388 return x;
1398} 1389}
1399EXPORT_SYMBOL(xfrm_state_lookup_byaddr); 1390EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
@@ -1405,9 +1396,9 @@ xfrm_find_acq(struct net *net, const struct xfrm_mark *mark, u8 mode, u32 reqid,
1405{ 1396{
1406 struct xfrm_state *x; 1397 struct xfrm_state *x;
1407 1398
1408 spin_lock_bh(&xfrm_state_lock); 1399 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1409 x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create); 1400 x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create);
1410 spin_unlock_bh(&xfrm_state_lock); 1401 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1411 1402
1412 return x; 1403 return x;
1413} 1404}
@@ -1416,17 +1407,17 @@ EXPORT_SYMBOL(xfrm_find_acq);
1416#ifdef CONFIG_XFRM_SUB_POLICY 1407#ifdef CONFIG_XFRM_SUB_POLICY
1417int 1408int
1418xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, 1409xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
1419 unsigned short family) 1410 unsigned short family, struct net *net)
1420{ 1411{
1421 int err = 0; 1412 int err = 0;
1422 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); 1413 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
1423 if (!afinfo) 1414 if (!afinfo)
1424 return -EAFNOSUPPORT; 1415 return -EAFNOSUPPORT;
1425 1416
1426 spin_lock_bh(&xfrm_state_lock); 1417 spin_lock_bh(&net->xfrm.xfrm_state_lock); /*FIXME*/
1427 if (afinfo->tmpl_sort) 1418 if (afinfo->tmpl_sort)
1428 err = afinfo->tmpl_sort(dst, src, n); 1419 err = afinfo->tmpl_sort(dst, src, n);
1429 spin_unlock_bh(&xfrm_state_lock); 1420 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1430 xfrm_state_put_afinfo(afinfo); 1421 xfrm_state_put_afinfo(afinfo);
1431 return err; 1422 return err;
1432} 1423}
@@ -1438,13 +1429,15 @@ xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1438{ 1429{
1439 int err = 0; 1430 int err = 0;
1440 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); 1431 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
1432 struct net *net = xs_net(*dst);
1433
1441 if (!afinfo) 1434 if (!afinfo)
1442 return -EAFNOSUPPORT; 1435 return -EAFNOSUPPORT;
1443 1436
1444 spin_lock_bh(&xfrm_state_lock); 1437 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1445 if (afinfo->state_sort) 1438 if (afinfo->state_sort)
1446 err = afinfo->state_sort(dst, src, n); 1439 err = afinfo->state_sort(dst, src, n);
1447 spin_unlock_bh(&xfrm_state_lock); 1440 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1448 xfrm_state_put_afinfo(afinfo); 1441 xfrm_state_put_afinfo(afinfo);
1449 return err; 1442 return err;
1450} 1443}
@@ -1476,9 +1469,9 @@ struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
1476{ 1469{
1477 struct xfrm_state *x; 1470 struct xfrm_state *x;
1478 1471
1479 spin_lock_bh(&xfrm_state_lock); 1472 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1480 x = __xfrm_find_acq_byseq(net, mark, seq); 1473 x = __xfrm_find_acq_byseq(net, mark, seq);
1481 spin_unlock_bh(&xfrm_state_lock); 1474 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1482 return x; 1475 return x;
1483} 1476}
1484EXPORT_SYMBOL(xfrm_find_acq_byseq); 1477EXPORT_SYMBOL(xfrm_find_acq_byseq);
@@ -1496,6 +1489,30 @@ u32 xfrm_get_acqseq(void)
1496} 1489}
1497EXPORT_SYMBOL(xfrm_get_acqseq); 1490EXPORT_SYMBOL(xfrm_get_acqseq);
1498 1491
1492int verify_spi_info(u8 proto, u32 min, u32 max)
1493{
1494 switch (proto) {
1495 case IPPROTO_AH:
1496 case IPPROTO_ESP:
1497 break;
1498
1499 case IPPROTO_COMP:
1500 /* IPCOMP spi is 16-bits. */
1501 if (max >= 0x10000)
1502 return -EINVAL;
1503 break;
1504
1505 default:
1506 return -EINVAL;
1507 }
1508
1509 if (min > max)
1510 return -EINVAL;
1511
1512 return 0;
1513}
1514EXPORT_SYMBOL(verify_spi_info);
1515
1499int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) 1516int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
1500{ 1517{
1501 struct net *net = xs_net(x); 1518 struct net *net = xs_net(x);
@@ -1536,10 +1553,10 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
1536 } 1553 }
1537 } 1554 }
1538 if (x->id.spi) { 1555 if (x->id.spi) {
1539 spin_lock_bh(&xfrm_state_lock); 1556 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); 1557 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); 1558 hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
1542 spin_unlock_bh(&xfrm_state_lock); 1559 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1543 1560
1544 err = 0; 1561 err = 0;
1545 } 1562 }
@@ -1562,7 +1579,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1562 if (walk->seq != 0 && list_empty(&walk->all)) 1579 if (walk->seq != 0 && list_empty(&walk->all))
1563 return 0; 1580 return 0;
1564 1581
1565 spin_lock_bh(&xfrm_state_lock); 1582 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1566 if (list_empty(&walk->all)) 1583 if (list_empty(&walk->all))
1567 x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all); 1584 x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all);
1568 else 1585 else
@@ -1586,7 +1603,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1586 } 1603 }
1587 list_del_init(&walk->all); 1604 list_del_init(&walk->all);
1588out: 1605out:
1589 spin_unlock_bh(&xfrm_state_lock); 1606 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1590 return err; 1607 return err;
1591} 1608}
1592EXPORT_SYMBOL(xfrm_state_walk); 1609EXPORT_SYMBOL(xfrm_state_walk);
@@ -1600,14 +1617,14 @@ void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
1600} 1617}
1601EXPORT_SYMBOL(xfrm_state_walk_init); 1618EXPORT_SYMBOL(xfrm_state_walk_init);
1602 1619
1603void xfrm_state_walk_done(struct xfrm_state_walk *walk) 1620void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net)
1604{ 1621{
1605 if (list_empty(&walk->all)) 1622 if (list_empty(&walk->all))
1606 return; 1623 return;
1607 1624
1608 spin_lock_bh(&xfrm_state_lock); 1625 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1609 list_del(&walk->all); 1626 list_del(&walk->all);
1610 spin_unlock_bh(&xfrm_state_lock); 1627 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1611} 1628}
1612EXPORT_SYMBOL(xfrm_state_walk_done); 1629EXPORT_SYMBOL(xfrm_state_walk_done);
1613 1630
@@ -1655,16 +1672,12 @@ EXPORT_SYMBOL(km_state_notify);
1655 1672
1656void km_state_expired(struct xfrm_state *x, int hard, u32 portid) 1673void km_state_expired(struct xfrm_state *x, int hard, u32 portid)
1657{ 1674{
1658 struct net *net = xs_net(x);
1659 struct km_event c; 1675 struct km_event c;
1660 1676
1661 c.data.hard = hard; 1677 c.data.hard = hard;
1662 c.portid = portid; 1678 c.portid = portid;
1663 c.event = XFRM_MSG_EXPIRE; 1679 c.event = XFRM_MSG_EXPIRE;
1664 km_state_notify(x, &c); 1680 km_state_notify(x, &c);
1665
1666 if (hard)
1667 wake_up(&net->xfrm.km_waitq);
1668} 1681}
1669 1682
1670EXPORT_SYMBOL(km_state_expired); 1683EXPORT_SYMBOL(km_state_expired);
@@ -1707,16 +1720,12 @@ EXPORT_SYMBOL(km_new_mapping);
1707 1720
1708void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid) 1721void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid)
1709{ 1722{
1710 struct net *net = xp_net(pol);
1711 struct km_event c; 1723 struct km_event c;
1712 1724
1713 c.data.hard = hard; 1725 c.data.hard = hard;
1714 c.portid = portid; 1726 c.portid = portid;
1715 c.event = XFRM_MSG_POLEXPIRE; 1727 c.event = XFRM_MSG_POLEXPIRE;
1716 km_policy_notify(pol, dir, &c); 1728 km_policy_notify(pol, dir, &c);
1717
1718 if (hard)
1719 wake_up(&net->xfrm.km_waitq);
1720} 1729}
1721EXPORT_SYMBOL(km_policy_expired); 1730EXPORT_SYMBOL(km_policy_expired);
1722 1731
@@ -2025,7 +2034,7 @@ int __net_init xfrm_state_init(struct net *net)
2025 INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize); 2034 INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize);
2026 INIT_HLIST_HEAD(&net->xfrm.state_gc_list); 2035 INIT_HLIST_HEAD(&net->xfrm.state_gc_list);
2027 INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task); 2036 INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task);
2028 init_waitqueue_head(&net->xfrm.km_waitq); 2037 spin_lock_init(&net->xfrm.xfrm_state_lock);
2029 return 0; 2038 return 0;
2030 2039
2031out_byspi: 2040out_byspi: