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.c216
1 files changed, 129 insertions, 87 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 68c2f357a183..40f1b3e92e78 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);
@@ -1147,6 +1159,11 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
1147 } 1159 }
1148 x->props.aalgo = orig->props.aalgo; 1160 x->props.aalgo = orig->props.aalgo;
1149 1161
1162 if (orig->aead) {
1163 x->aead = xfrm_algo_aead_clone(orig->aead);
1164 if (!x->aead)
1165 goto error;
1166 }
1150 if (orig->ealg) { 1167 if (orig->ealg) {
1151 x->ealg = xfrm_algo_clone(orig->ealg); 1168 x->ealg = xfrm_algo_clone(orig->ealg);
1152 if (!x->ealg) 1169 if (!x->ealg)
@@ -1189,6 +1206,9 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
1189 x->props.flags = orig->props.flags; 1206 x->props.flags = orig->props.flags;
1190 x->props.extra_flags = orig->props.extra_flags; 1207 x->props.extra_flags = orig->props.extra_flags;
1191 1208
1209 x->tfcpad = orig->tfcpad;
1210 x->replay_maxdiff = orig->replay_maxdiff;
1211 x->replay_maxage = orig->replay_maxage;
1192 x->curlft.add_time = orig->curlft.add_time; 1212 x->curlft.add_time = orig->curlft.add_time;
1193 x->km.state = orig->km.state; 1213 x->km.state = orig->km.state;
1194 x->km.seq = orig->km.seq; 1214 x->km.seq = orig->km.seq;
@@ -1203,16 +1223,17 @@ out:
1203 return NULL; 1223 return NULL;
1204} 1224}
1205 1225
1206/* xfrm_state_lock is held */ 1226struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net)
1207struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
1208{ 1227{
1209 unsigned int h; 1228 unsigned int h;
1210 struct xfrm_state *x; 1229 struct xfrm_state *x = NULL;
1230
1231 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1211 1232
1212 if (m->reqid) { 1233 if (m->reqid) {
1213 h = xfrm_dst_hash(&init_net, &m->old_daddr, &m->old_saddr, 1234 h = xfrm_dst_hash(net, &m->old_daddr, &m->old_saddr,
1214 m->reqid, m->old_family); 1235 m->reqid, m->old_family);
1215 hlist_for_each_entry(x, init_net.xfrm.state_bydst+h, bydst) { 1236 hlist_for_each_entry(x, net->xfrm.state_bydst+h, bydst) {
1216 if (x->props.mode != m->mode || 1237 if (x->props.mode != m->mode ||
1217 x->id.proto != m->proto) 1238 x->id.proto != m->proto)
1218 continue; 1239 continue;
@@ -1224,12 +1245,12 @@ struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
1224 m->old_family)) 1245 m->old_family))
1225 continue; 1246 continue;
1226 xfrm_state_hold(x); 1247 xfrm_state_hold(x);
1227 return x; 1248 break;
1228 } 1249 }
1229 } else { 1250 } else {
1230 h = xfrm_src_hash(&init_net, &m->old_daddr, &m->old_saddr, 1251 h = xfrm_src_hash(net, &m->old_daddr, &m->old_saddr,
1231 m->old_family); 1252 m->old_family);
1232 hlist_for_each_entry(x, init_net.xfrm.state_bysrc+h, bysrc) { 1253 hlist_for_each_entry(x, net->xfrm.state_bysrc+h, bysrc) {
1233 if (x->props.mode != m->mode || 1254 if (x->props.mode != m->mode ||
1234 x->id.proto != m->proto) 1255 x->id.proto != m->proto)
1235 continue; 1256 continue;
@@ -1239,16 +1260,18 @@ struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
1239 m->old_family)) 1260 m->old_family))
1240 continue; 1261 continue;
1241 xfrm_state_hold(x); 1262 xfrm_state_hold(x);
1242 return x; 1263 break;
1243 } 1264 }
1244 } 1265 }
1245 1266
1246 return NULL; 1267 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1268
1269 return x;
1247} 1270}
1248EXPORT_SYMBOL(xfrm_migrate_state_find); 1271EXPORT_SYMBOL(xfrm_migrate_state_find);
1249 1272
1250struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x, 1273struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
1251 struct xfrm_migrate *m) 1274 struct xfrm_migrate *m)
1252{ 1275{
1253 struct xfrm_state *xc; 1276 struct xfrm_state *xc;
1254 int err; 1277 int err;
@@ -1283,10 +1306,11 @@ int xfrm_state_update(struct xfrm_state *x)
1283 struct xfrm_state *x1, *to_put; 1306 struct xfrm_state *x1, *to_put;
1284 int err; 1307 int err;
1285 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY); 1308 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
1309 struct net *net = xs_net(x);
1286 1310
1287 to_put = NULL; 1311 to_put = NULL;
1288 1312
1289 spin_lock_bh(&xfrm_state_lock); 1313 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1290 x1 = __xfrm_state_locate(x, use_spi, x->props.family); 1314 x1 = __xfrm_state_locate(x, use_spi, x->props.family);
1291 1315
1292 err = -ESRCH; 1316 err = -ESRCH;
@@ -1306,7 +1330,7 @@ int xfrm_state_update(struct xfrm_state *x)
1306 err = 0; 1330 err = 0;
1307 1331
1308out: 1332out:
1309 spin_unlock_bh(&xfrm_state_lock); 1333 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1310 1334
1311 if (to_put) 1335 if (to_put)
1312 xfrm_state_put(to_put); 1336 xfrm_state_put(to_put);
@@ -1357,7 +1381,7 @@ int xfrm_state_check_expire(struct xfrm_state *x)
1357 if (x->curlft.bytes >= x->lft.hard_byte_limit || 1381 if (x->curlft.bytes >= x->lft.hard_byte_limit ||
1358 x->curlft.packets >= x->lft.hard_packet_limit) { 1382 x->curlft.packets >= x->lft.hard_packet_limit) {
1359 x->km.state = XFRM_STATE_EXPIRED; 1383 x->km.state = XFRM_STATE_EXPIRED;
1360 tasklet_hrtimer_start(&x->mtimer, ktime_set(0,0), HRTIMER_MODE_REL); 1384 tasklet_hrtimer_start(&x->mtimer, ktime_set(0, 0), HRTIMER_MODE_REL);
1361 return -EINVAL; 1385 return -EINVAL;
1362 } 1386 }
1363 1387
@@ -1377,9 +1401,9 @@ xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32
1377{ 1401{
1378 struct xfrm_state *x; 1402 struct xfrm_state *x;
1379 1403
1380 spin_lock_bh(&xfrm_state_lock); 1404 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1381 x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family); 1405 x = __xfrm_state_lookup(net, mark, daddr, spi, proto, family);
1382 spin_unlock_bh(&xfrm_state_lock); 1406 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1383 return x; 1407 return x;
1384} 1408}
1385EXPORT_SYMBOL(xfrm_state_lookup); 1409EXPORT_SYMBOL(xfrm_state_lookup);
@@ -1391,9 +1415,9 @@ xfrm_state_lookup_byaddr(struct net *net, u32 mark,
1391{ 1415{
1392 struct xfrm_state *x; 1416 struct xfrm_state *x;
1393 1417
1394 spin_lock_bh(&xfrm_state_lock); 1418 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1395 x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family); 1419 x = __xfrm_state_lookup_byaddr(net, mark, daddr, saddr, proto, family);
1396 spin_unlock_bh(&xfrm_state_lock); 1420 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1397 return x; 1421 return x;
1398} 1422}
1399EXPORT_SYMBOL(xfrm_state_lookup_byaddr); 1423EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
@@ -1405,9 +1429,9 @@ xfrm_find_acq(struct net *net, const struct xfrm_mark *mark, u8 mode, u32 reqid,
1405{ 1429{
1406 struct xfrm_state *x; 1430 struct xfrm_state *x;
1407 1431
1408 spin_lock_bh(&xfrm_state_lock); 1432 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1409 x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create); 1433 x = __find_acq_core(net, mark, family, mode, reqid, proto, daddr, saddr, create);
1410 spin_unlock_bh(&xfrm_state_lock); 1434 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1411 1435
1412 return x; 1436 return x;
1413} 1437}
@@ -1416,17 +1440,17 @@ EXPORT_SYMBOL(xfrm_find_acq);
1416#ifdef CONFIG_XFRM_SUB_POLICY 1440#ifdef CONFIG_XFRM_SUB_POLICY
1417int 1441int
1418xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, 1442xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n,
1419 unsigned short family) 1443 unsigned short family, struct net *net)
1420{ 1444{
1421 int err = 0; 1445 int err = 0;
1422 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); 1446 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
1423 if (!afinfo) 1447 if (!afinfo)
1424 return -EAFNOSUPPORT; 1448 return -EAFNOSUPPORT;
1425 1449
1426 spin_lock_bh(&xfrm_state_lock); 1450 spin_lock_bh(&net->xfrm.xfrm_state_lock); /*FIXME*/
1427 if (afinfo->tmpl_sort) 1451 if (afinfo->tmpl_sort)
1428 err = afinfo->tmpl_sort(dst, src, n); 1452 err = afinfo->tmpl_sort(dst, src, n);
1429 spin_unlock_bh(&xfrm_state_lock); 1453 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1430 xfrm_state_put_afinfo(afinfo); 1454 xfrm_state_put_afinfo(afinfo);
1431 return err; 1455 return err;
1432} 1456}
@@ -1438,13 +1462,15 @@ xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n,
1438{ 1462{
1439 int err = 0; 1463 int err = 0;
1440 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); 1464 struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
1465 struct net *net = xs_net(*src);
1466
1441 if (!afinfo) 1467 if (!afinfo)
1442 return -EAFNOSUPPORT; 1468 return -EAFNOSUPPORT;
1443 1469
1444 spin_lock_bh(&xfrm_state_lock); 1470 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1445 if (afinfo->state_sort) 1471 if (afinfo->state_sort)
1446 err = afinfo->state_sort(dst, src, n); 1472 err = afinfo->state_sort(dst, src, n);
1447 spin_unlock_bh(&xfrm_state_lock); 1473 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1448 xfrm_state_put_afinfo(afinfo); 1474 xfrm_state_put_afinfo(afinfo);
1449 return err; 1475 return err;
1450} 1476}
@@ -1476,9 +1502,9 @@ struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq)
1476{ 1502{
1477 struct xfrm_state *x; 1503 struct xfrm_state *x;
1478 1504
1479 spin_lock_bh(&xfrm_state_lock); 1505 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1480 x = __xfrm_find_acq_byseq(net, mark, seq); 1506 x = __xfrm_find_acq_byseq(net, mark, seq);
1481 spin_unlock_bh(&xfrm_state_lock); 1507 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1482 return x; 1508 return x;
1483} 1509}
1484EXPORT_SYMBOL(xfrm_find_acq_byseq); 1510EXPORT_SYMBOL(xfrm_find_acq_byseq);
@@ -1496,6 +1522,30 @@ u32 xfrm_get_acqseq(void)
1496} 1522}
1497EXPORT_SYMBOL(xfrm_get_acqseq); 1523EXPORT_SYMBOL(xfrm_get_acqseq);
1498 1524
1525int verify_spi_info(u8 proto, u32 min, u32 max)
1526{
1527 switch (proto) {
1528 case IPPROTO_AH:
1529 case IPPROTO_ESP:
1530 break;
1531
1532 case IPPROTO_COMP:
1533 /* IPCOMP spi is 16-bits. */
1534 if (max >= 0x10000)
1535 return -EINVAL;
1536 break;
1537
1538 default:
1539 return -EINVAL;
1540 }
1541
1542 if (min > max)
1543 return -EINVAL;
1544
1545 return 0;
1546}
1547EXPORT_SYMBOL(verify_spi_info);
1548
1499int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) 1549int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
1500{ 1550{
1501 struct net *net = xs_net(x); 1551 struct net *net = xs_net(x);
@@ -1525,8 +1575,8 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
1525 x->id.spi = minspi; 1575 x->id.spi = minspi;
1526 } else { 1576 } else {
1527 u32 spi = 0; 1577 u32 spi = 0;
1528 for (h=0; h<high-low+1; h++) { 1578 for (h = 0; h < high-low+1; h++) {
1529 spi = low + net_random()%(high-low+1); 1579 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); 1580 x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
1531 if (x0 == NULL) { 1581 if (x0 == NULL) {
1532 x->id.spi = htonl(spi); 1582 x->id.spi = htonl(spi);
@@ -1536,10 +1586,10 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
1536 } 1586 }
1537 } 1587 }
1538 if (x->id.spi) { 1588 if (x->id.spi) {
1539 spin_lock_bh(&xfrm_state_lock); 1589 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); 1590 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); 1591 hlist_add_head(&x->byspi, net->xfrm.state_byspi+h);
1542 spin_unlock_bh(&xfrm_state_lock); 1592 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1543 1593
1544 err = 0; 1594 err = 0;
1545 } 1595 }
@@ -1562,7 +1612,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1562 if (walk->seq != 0 && list_empty(&walk->all)) 1612 if (walk->seq != 0 && list_empty(&walk->all))
1563 return 0; 1613 return 0;
1564 1614
1565 spin_lock_bh(&xfrm_state_lock); 1615 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1566 if (list_empty(&walk->all)) 1616 if (list_empty(&walk->all))
1567 x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all); 1617 x = list_first_entry(&net->xfrm.state_all, struct xfrm_state_walk, all);
1568 else 1618 else
@@ -1586,7 +1636,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
1586 } 1636 }
1587 list_del_init(&walk->all); 1637 list_del_init(&walk->all);
1588out: 1638out:
1589 spin_unlock_bh(&xfrm_state_lock); 1639 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1590 return err; 1640 return err;
1591} 1641}
1592EXPORT_SYMBOL(xfrm_state_walk); 1642EXPORT_SYMBOL(xfrm_state_walk);
@@ -1600,20 +1650,20 @@ void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
1600} 1650}
1601EXPORT_SYMBOL(xfrm_state_walk_init); 1651EXPORT_SYMBOL(xfrm_state_walk_init);
1602 1652
1603void xfrm_state_walk_done(struct xfrm_state_walk *walk) 1653void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net)
1604{ 1654{
1605 if (list_empty(&walk->all)) 1655 if (list_empty(&walk->all))
1606 return; 1656 return;
1607 1657
1608 spin_lock_bh(&xfrm_state_lock); 1658 spin_lock_bh(&net->xfrm.xfrm_state_lock);
1609 list_del(&walk->all); 1659 list_del(&walk->all);
1610 spin_unlock_bh(&xfrm_state_lock); 1660 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
1611} 1661}
1612EXPORT_SYMBOL(xfrm_state_walk_done); 1662EXPORT_SYMBOL(xfrm_state_walk_done);
1613 1663
1614static void xfrm_replay_timer_handler(unsigned long data) 1664static void xfrm_replay_timer_handler(unsigned long data)
1615{ 1665{
1616 struct xfrm_state *x = (struct xfrm_state*)data; 1666 struct xfrm_state *x = (struct xfrm_state *)data;
1617 1667
1618 spin_lock(&x->lock); 1668 spin_lock(&x->lock);
1619 1669
@@ -1655,16 +1705,12 @@ EXPORT_SYMBOL(km_state_notify);
1655 1705
1656void km_state_expired(struct xfrm_state *x, int hard, u32 portid) 1706void km_state_expired(struct xfrm_state *x, int hard, u32 portid)
1657{ 1707{
1658 struct net *net = xs_net(x);
1659 struct km_event c; 1708 struct km_event c;
1660 1709
1661 c.data.hard = hard; 1710 c.data.hard = hard;
1662 c.portid = portid; 1711 c.portid = portid;
1663 c.event = XFRM_MSG_EXPIRE; 1712 c.event = XFRM_MSG_EXPIRE;
1664 km_state_notify(x, &c); 1713 km_state_notify(x, &c);
1665
1666 if (hard)
1667 wake_up(&net->xfrm.km_waitq);
1668} 1714}
1669 1715
1670EXPORT_SYMBOL(km_state_expired); 1716EXPORT_SYMBOL(km_state_expired);
@@ -1707,16 +1753,12 @@ EXPORT_SYMBOL(km_new_mapping);
1707 1753
1708void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid) 1754void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid)
1709{ 1755{
1710 struct net *net = xp_net(pol);
1711 struct km_event c; 1756 struct km_event c;
1712 1757
1713 c.data.hard = hard; 1758 c.data.hard = hard;
1714 c.portid = portid; 1759 c.portid = portid;
1715 c.event = XFRM_MSG_POLEXPIRE; 1760 c.event = XFRM_MSG_POLEXPIRE;
1716 km_policy_notify(pol, dir, &c); 1761 km_policy_notify(pol, dir, &c);
1717
1718 if (hard)
1719 wake_up(&net->xfrm.km_waitq);
1720} 1762}
1721EXPORT_SYMBOL(km_policy_expired); 1763EXPORT_SYMBOL(km_policy_expired);
1722 1764
@@ -2025,7 +2067,7 @@ int __net_init xfrm_state_init(struct net *net)
2025 INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize); 2067 INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize);
2026 INIT_HLIST_HEAD(&net->xfrm.state_gc_list); 2068 INIT_HLIST_HEAD(&net->xfrm.state_gc_list);
2027 INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task); 2069 INIT_WORK(&net->xfrm.state_gc_work, xfrm_state_gc_task);
2028 init_waitqueue_head(&net->xfrm.km_waitq); 2070 spin_lock_init(&net->xfrm.xfrm_state_lock);
2029 return 0; 2071 return 0;
2030 2072
2031out_byspi: 2073out_byspi:
@@ -2043,7 +2085,7 @@ void xfrm_state_fini(struct net *net)
2043 2085
2044 flush_work(&net->xfrm.state_hash_work); 2086 flush_work(&net->xfrm.state_hash_work);
2045 audit_info.loginuid = INVALID_UID; 2087 audit_info.loginuid = INVALID_UID;
2046 audit_info.sessionid = -1; 2088 audit_info.sessionid = (unsigned int)-1;
2047 audit_info.secid = 0; 2089 audit_info.secid = 0;
2048 xfrm_state_flush(net, IPSEC_PROTO_ANY, &audit_info); 2090 xfrm_state_flush(net, IPSEC_PROTO_ANY, &audit_info);
2049 flush_work(&net->xfrm.state_gc_work); 2091 flush_work(&net->xfrm.state_gc_work);
@@ -2070,7 +2112,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", 2112 audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
2071 ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str); 2113 ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
2072 2114
2073 switch(x->props.family) { 2115 switch (x->props.family) {
2074 case AF_INET: 2116 case AF_INET:
2075 audit_log_format(audit_buf, " src=%pI4 dst=%pI4", 2117 audit_log_format(audit_buf, " src=%pI4 dst=%pI4",
2076 &x->props.saddr.a4, &x->id.daddr.a4); 2118 &x->props.saddr.a4, &x->id.daddr.a4);
@@ -2100,7 +2142,7 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
2100 iph6 = ipv6_hdr(skb); 2142 iph6 = ipv6_hdr(skb);
2101 audit_log_format(audit_buf, 2143 audit_log_format(audit_buf,
2102 " src=%pI6 dst=%pI6 flowlbl=0x%x%02x%02x", 2144 " src=%pI6 dst=%pI6 flowlbl=0x%x%02x%02x",
2103 &iph6->saddr,&iph6->daddr, 2145 &iph6->saddr, &iph6->daddr,
2104 iph6->flow_lbl[0] & 0x0f, 2146 iph6->flow_lbl[0] & 0x0f,
2105 iph6->flow_lbl[1], 2147 iph6->flow_lbl[1],
2106 iph6->flow_lbl[2]); 2148 iph6->flow_lbl[2]);
@@ -2109,7 +2151,7 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
2109} 2151}
2110 2152
2111void xfrm_audit_state_add(struct xfrm_state *x, int result, 2153void xfrm_audit_state_add(struct xfrm_state *x, int result,
2112 kuid_t auid, u32 sessionid, u32 secid) 2154 kuid_t auid, unsigned int sessionid, u32 secid)
2113{ 2155{
2114 struct audit_buffer *audit_buf; 2156 struct audit_buffer *audit_buf;
2115 2157
@@ -2124,7 +2166,7 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result,
2124EXPORT_SYMBOL_GPL(xfrm_audit_state_add); 2166EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
2125 2167
2126void xfrm_audit_state_delete(struct xfrm_state *x, int result, 2168void xfrm_audit_state_delete(struct xfrm_state *x, int result,
2127 kuid_t auid, u32 sessionid, u32 secid) 2169 kuid_t auid, unsigned int sessionid, u32 secid)
2128{ 2170{
2129 struct audit_buffer *audit_buf; 2171 struct audit_buffer *audit_buf;
2130 2172