diff options
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r-- | net/xfrm/xfrm_user.c | 249 |
1 files changed, 178 insertions, 71 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index a278a6f3b991..b95a2d64eb59 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -316,11 +316,12 @@ static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs) | |||
316 | x->replay_maxdiff = nla_get_u32(rt); | 316 | x->replay_maxdiff = nla_get_u32(rt); |
317 | } | 317 | } |
318 | 318 | ||
319 | static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p, | 319 | static struct xfrm_state *xfrm_state_construct(struct net *net, |
320 | struct xfrm_usersa_info *p, | ||
320 | struct nlattr **attrs, | 321 | struct nlattr **attrs, |
321 | int *errp) | 322 | int *errp) |
322 | { | 323 | { |
323 | struct xfrm_state *x = xfrm_state_alloc(); | 324 | struct xfrm_state *x = xfrm_state_alloc(net); |
324 | int err = -ENOMEM; | 325 | int err = -ENOMEM; |
325 | 326 | ||
326 | if (!x) | 327 | if (!x) |
@@ -367,9 +368,9 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p, | |||
367 | goto error; | 368 | goto error; |
368 | 369 | ||
369 | x->km.seq = p->seq; | 370 | x->km.seq = p->seq; |
370 | x->replay_maxdiff = sysctl_xfrm_aevent_rseqth; | 371 | x->replay_maxdiff = net->xfrm.sysctl_aevent_rseqth; |
371 | /* sysctl_xfrm_aevent_etime is in 100ms units */ | 372 | /* sysctl_xfrm_aevent_etime is in 100ms units */ |
372 | x->replay_maxage = (sysctl_xfrm_aevent_etime*HZ)/XFRM_AE_ETH_M; | 373 | x->replay_maxage = (net->xfrm.sysctl_aevent_etime*HZ)/XFRM_AE_ETH_M; |
373 | x->preplay.bitmap = 0; | 374 | x->preplay.bitmap = 0; |
374 | x->preplay.seq = x->replay.seq+x->replay_maxdiff; | 375 | x->preplay.seq = x->replay.seq+x->replay_maxdiff; |
375 | x->preplay.oseq = x->replay.oseq +x->replay_maxdiff; | 376 | x->preplay.oseq = x->replay.oseq +x->replay_maxdiff; |
@@ -391,6 +392,7 @@ error_no_put: | |||
391 | static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | 392 | static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, |
392 | struct nlattr **attrs) | 393 | struct nlattr **attrs) |
393 | { | 394 | { |
395 | struct net *net = sock_net(skb->sk); | ||
394 | struct xfrm_usersa_info *p = nlmsg_data(nlh); | 396 | struct xfrm_usersa_info *p = nlmsg_data(nlh); |
395 | struct xfrm_state *x; | 397 | struct xfrm_state *x; |
396 | int err; | 398 | int err; |
@@ -403,7 +405,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
403 | if (err) | 405 | if (err) |
404 | return err; | 406 | return err; |
405 | 407 | ||
406 | x = xfrm_state_construct(p, attrs, &err); | 408 | x = xfrm_state_construct(net, p, attrs, &err); |
407 | if (!x) | 409 | if (!x) |
408 | return err; | 410 | return err; |
409 | 411 | ||
@@ -431,7 +433,8 @@ out: | |||
431 | return err; | 433 | return err; |
432 | } | 434 | } |
433 | 435 | ||
434 | static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p, | 436 | static struct xfrm_state *xfrm_user_state_lookup(struct net *net, |
437 | struct xfrm_usersa_id *p, | ||
435 | struct nlattr **attrs, | 438 | struct nlattr **attrs, |
436 | int *errp) | 439 | int *errp) |
437 | { | 440 | { |
@@ -440,7 +443,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p, | |||
440 | 443 | ||
441 | if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) { | 444 | if (xfrm_id_proto_match(p->proto, IPSEC_PROTO_ANY)) { |
442 | err = -ESRCH; | 445 | err = -ESRCH; |
443 | x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family); | 446 | x = xfrm_state_lookup(net, &p->daddr, p->spi, p->proto, p->family); |
444 | } else { | 447 | } else { |
445 | xfrm_address_t *saddr = NULL; | 448 | xfrm_address_t *saddr = NULL; |
446 | 449 | ||
@@ -451,8 +454,8 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p, | |||
451 | } | 454 | } |
452 | 455 | ||
453 | err = -ESRCH; | 456 | err = -ESRCH; |
454 | x = xfrm_state_lookup_byaddr(&p->daddr, saddr, p->proto, | 457 | x = xfrm_state_lookup_byaddr(net, &p->daddr, saddr, |
455 | p->family); | 458 | p->proto, p->family); |
456 | } | 459 | } |
457 | 460 | ||
458 | out: | 461 | out: |
@@ -464,6 +467,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p, | |||
464 | static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | 467 | static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, |
465 | struct nlattr **attrs) | 468 | struct nlattr **attrs) |
466 | { | 469 | { |
470 | struct net *net = sock_net(skb->sk); | ||
467 | struct xfrm_state *x; | 471 | struct xfrm_state *x; |
468 | int err = -ESRCH; | 472 | int err = -ESRCH; |
469 | struct km_event c; | 473 | struct km_event c; |
@@ -472,7 +476,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
472 | u32 sessionid = NETLINK_CB(skb).sessionid; | 476 | u32 sessionid = NETLINK_CB(skb).sessionid; |
473 | u32 sid = NETLINK_CB(skb).sid; | 477 | u32 sid = NETLINK_CB(skb).sid; |
474 | 478 | ||
475 | x = xfrm_user_state_lookup(p, attrs, &err); | 479 | x = xfrm_user_state_lookup(net, p, attrs, &err); |
476 | if (x == NULL) | 480 | if (x == NULL) |
477 | return err; | 481 | return err; |
478 | 482 | ||
@@ -615,6 +619,7 @@ static int xfrm_dump_sa_done(struct netlink_callback *cb) | |||
615 | 619 | ||
616 | static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) | 620 | static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) |
617 | { | 621 | { |
622 | struct net *net = sock_net(skb->sk); | ||
618 | struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1]; | 623 | struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1]; |
619 | struct xfrm_dump_info info; | 624 | struct xfrm_dump_info info; |
620 | 625 | ||
@@ -631,7 +636,7 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) | |||
631 | xfrm_state_walk_init(walk, 0); | 636 | xfrm_state_walk_init(walk, 0); |
632 | } | 637 | } |
633 | 638 | ||
634 | (void) xfrm_state_walk(walk, dump_one_state, &info); | 639 | (void) xfrm_state_walk(net, walk, dump_one_state, &info); |
635 | 640 | ||
636 | return skb->len; | 641 | return skb->len; |
637 | } | 642 | } |
@@ -703,6 +708,7 @@ nla_put_failure: | |||
703 | static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | 708 | static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh, |
704 | struct nlattr **attrs) | 709 | struct nlattr **attrs) |
705 | { | 710 | { |
711 | struct net *net = sock_net(skb->sk); | ||
706 | struct sk_buff *r_skb; | 712 | struct sk_buff *r_skb; |
707 | u32 *flags = nlmsg_data(nlh); | 713 | u32 *flags = nlmsg_data(nlh); |
708 | u32 spid = NETLINK_CB(skb).pid; | 714 | u32 spid = NETLINK_CB(skb).pid; |
@@ -715,7 +721,7 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
715 | if (build_spdinfo(r_skb, spid, seq, *flags) < 0) | 721 | if (build_spdinfo(r_skb, spid, seq, *flags) < 0) |
716 | BUG(); | 722 | BUG(); |
717 | 723 | ||
718 | return nlmsg_unicast(xfrm_nl, r_skb, spid); | 724 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid); |
719 | } | 725 | } |
720 | 726 | ||
721 | static inline size_t xfrm_sadinfo_msgsize(void) | 727 | static inline size_t xfrm_sadinfo_msgsize(void) |
@@ -756,6 +762,7 @@ nla_put_failure: | |||
756 | static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | 762 | static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh, |
757 | struct nlattr **attrs) | 763 | struct nlattr **attrs) |
758 | { | 764 | { |
765 | struct net *net = sock_net(skb->sk); | ||
759 | struct sk_buff *r_skb; | 766 | struct sk_buff *r_skb; |
760 | u32 *flags = nlmsg_data(nlh); | 767 | u32 *flags = nlmsg_data(nlh); |
761 | u32 spid = NETLINK_CB(skb).pid; | 768 | u32 spid = NETLINK_CB(skb).pid; |
@@ -768,18 +775,19 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
768 | if (build_sadinfo(r_skb, spid, seq, *flags) < 0) | 775 | if (build_sadinfo(r_skb, spid, seq, *flags) < 0) |
769 | BUG(); | 776 | BUG(); |
770 | 777 | ||
771 | return nlmsg_unicast(xfrm_nl, r_skb, spid); | 778 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, spid); |
772 | } | 779 | } |
773 | 780 | ||
774 | static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | 781 | static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, |
775 | struct nlattr **attrs) | 782 | struct nlattr **attrs) |
776 | { | 783 | { |
784 | struct net *net = sock_net(skb->sk); | ||
777 | struct xfrm_usersa_id *p = nlmsg_data(nlh); | 785 | struct xfrm_usersa_id *p = nlmsg_data(nlh); |
778 | struct xfrm_state *x; | 786 | struct xfrm_state *x; |
779 | struct sk_buff *resp_skb; | 787 | struct sk_buff *resp_skb; |
780 | int err = -ESRCH; | 788 | int err = -ESRCH; |
781 | 789 | ||
782 | x = xfrm_user_state_lookup(p, attrs, &err); | 790 | x = xfrm_user_state_lookup(net, p, attrs, &err); |
783 | if (x == NULL) | 791 | if (x == NULL) |
784 | goto out_noput; | 792 | goto out_noput; |
785 | 793 | ||
@@ -787,7 +795,7 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
787 | if (IS_ERR(resp_skb)) { | 795 | if (IS_ERR(resp_skb)) { |
788 | err = PTR_ERR(resp_skb); | 796 | err = PTR_ERR(resp_skb); |
789 | } else { | 797 | } else { |
790 | err = nlmsg_unicast(xfrm_nl, resp_skb, NETLINK_CB(skb).pid); | 798 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).pid); |
791 | } | 799 | } |
792 | xfrm_state_put(x); | 800 | xfrm_state_put(x); |
793 | out_noput: | 801 | out_noput: |
@@ -820,6 +828,7 @@ static int verify_userspi_info(struct xfrm_userspi_info *p) | |||
820 | static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | 828 | static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, |
821 | struct nlattr **attrs) | 829 | struct nlattr **attrs) |
822 | { | 830 | { |
831 | struct net *net = sock_net(skb->sk); | ||
823 | struct xfrm_state *x; | 832 | struct xfrm_state *x; |
824 | struct xfrm_userspi_info *p; | 833 | struct xfrm_userspi_info *p; |
825 | struct sk_buff *resp_skb; | 834 | struct sk_buff *resp_skb; |
@@ -837,7 +846,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
837 | 846 | ||
838 | x = NULL; | 847 | x = NULL; |
839 | if (p->info.seq) { | 848 | if (p->info.seq) { |
840 | x = xfrm_find_acq_byseq(p->info.seq); | 849 | x = xfrm_find_acq_byseq(net, p->info.seq); |
841 | if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) { | 850 | if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) { |
842 | xfrm_state_put(x); | 851 | xfrm_state_put(x); |
843 | x = NULL; | 852 | x = NULL; |
@@ -845,7 +854,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
845 | } | 854 | } |
846 | 855 | ||
847 | if (!x) | 856 | if (!x) |
848 | x = xfrm_find_acq(p->info.mode, p->info.reqid, | 857 | x = xfrm_find_acq(net, p->info.mode, p->info.reqid, |
849 | p->info.id.proto, daddr, | 858 | p->info.id.proto, daddr, |
850 | &p->info.saddr, 1, | 859 | &p->info.saddr, 1, |
851 | family); | 860 | family); |
@@ -863,7 +872,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
863 | goto out; | 872 | goto out; |
864 | } | 873 | } |
865 | 874 | ||
866 | err = nlmsg_unicast(xfrm_nl, resp_skb, NETLINK_CB(skb).pid); | 875 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).pid); |
867 | 876 | ||
868 | out: | 877 | out: |
869 | xfrm_state_put(x); | 878 | xfrm_state_put(x); |
@@ -1078,9 +1087,9 @@ static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_i | |||
1078 | p->share = XFRM_SHARE_ANY; /* XXX xp->share */ | 1087 | p->share = XFRM_SHARE_ANY; /* XXX xp->share */ |
1079 | } | 1088 | } |
1080 | 1089 | ||
1081 | static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, struct nlattr **attrs, int *errp) | 1090 | static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_userpolicy_info *p, struct nlattr **attrs, int *errp) |
1082 | { | 1091 | { |
1083 | struct xfrm_policy *xp = xfrm_policy_alloc(GFP_KERNEL); | 1092 | struct xfrm_policy *xp = xfrm_policy_alloc(net, GFP_KERNEL); |
1084 | int err; | 1093 | int err; |
1085 | 1094 | ||
1086 | if (!xp) { | 1095 | if (!xp) { |
@@ -1110,6 +1119,7 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, | |||
1110 | static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | 1119 | static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, |
1111 | struct nlattr **attrs) | 1120 | struct nlattr **attrs) |
1112 | { | 1121 | { |
1122 | struct net *net = sock_net(skb->sk); | ||
1113 | struct xfrm_userpolicy_info *p = nlmsg_data(nlh); | 1123 | struct xfrm_userpolicy_info *p = nlmsg_data(nlh); |
1114 | struct xfrm_policy *xp; | 1124 | struct xfrm_policy *xp; |
1115 | struct km_event c; | 1125 | struct km_event c; |
@@ -1126,7 +1136,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1126 | if (err) | 1136 | if (err) |
1127 | return err; | 1137 | return err; |
1128 | 1138 | ||
1129 | xp = xfrm_policy_construct(p, attrs, &err); | 1139 | xp = xfrm_policy_construct(net, p, attrs, &err); |
1130 | if (!xp) | 1140 | if (!xp) |
1131 | return err; | 1141 | return err; |
1132 | 1142 | ||
@@ -1263,6 +1273,7 @@ static int xfrm_dump_policy_done(struct netlink_callback *cb) | |||
1263 | 1273 | ||
1264 | static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb) | 1274 | static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb) |
1265 | { | 1275 | { |
1276 | struct net *net = sock_net(skb->sk); | ||
1266 | struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; | 1277 | struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; |
1267 | struct xfrm_dump_info info; | 1278 | struct xfrm_dump_info info; |
1268 | 1279 | ||
@@ -1279,7 +1290,7 @@ static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1279 | xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY); | 1290 | xfrm_policy_walk_init(walk, XFRM_POLICY_TYPE_ANY); |
1280 | } | 1291 | } |
1281 | 1292 | ||
1282 | (void) xfrm_policy_walk(walk, dump_one_policy, &info); | 1293 | (void) xfrm_policy_walk(net, walk, dump_one_policy, &info); |
1283 | 1294 | ||
1284 | return skb->len; | 1295 | return skb->len; |
1285 | } | 1296 | } |
@@ -1311,6 +1322,7 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb, | |||
1311 | static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | 1322 | static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, |
1312 | struct nlattr **attrs) | 1323 | struct nlattr **attrs) |
1313 | { | 1324 | { |
1325 | struct net *net = sock_net(skb->sk); | ||
1314 | struct xfrm_policy *xp; | 1326 | struct xfrm_policy *xp; |
1315 | struct xfrm_userpolicy_id *p; | 1327 | struct xfrm_userpolicy_id *p; |
1316 | u8 type = XFRM_POLICY_TYPE_MAIN; | 1328 | u8 type = XFRM_POLICY_TYPE_MAIN; |
@@ -1330,7 +1342,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1330 | return err; | 1342 | return err; |
1331 | 1343 | ||
1332 | if (p->index) | 1344 | if (p->index) |
1333 | xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err); | 1345 | xp = xfrm_policy_byid(net, type, p->dir, p->index, delete, &err); |
1334 | else { | 1346 | else { |
1335 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; | 1347 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; |
1336 | struct xfrm_sec_ctx *ctx; | 1348 | struct xfrm_sec_ctx *ctx; |
@@ -1347,7 +1359,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1347 | if (err) | 1359 | if (err) |
1348 | return err; | 1360 | return err; |
1349 | } | 1361 | } |
1350 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, ctx, | 1362 | xp = xfrm_policy_bysel_ctx(net, type, p->dir, &p->sel, ctx, |
1351 | delete, &err); | 1363 | delete, &err); |
1352 | security_xfrm_policy_free(ctx); | 1364 | security_xfrm_policy_free(ctx); |
1353 | } | 1365 | } |
@@ -1361,7 +1373,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1361 | if (IS_ERR(resp_skb)) { | 1373 | if (IS_ERR(resp_skb)) { |
1362 | err = PTR_ERR(resp_skb); | 1374 | err = PTR_ERR(resp_skb); |
1363 | } else { | 1375 | } else { |
1364 | err = nlmsg_unicast(xfrm_nl, resp_skb, | 1376 | err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, |
1365 | NETLINK_CB(skb).pid); | 1377 | NETLINK_CB(skb).pid); |
1366 | } | 1378 | } |
1367 | } else { | 1379 | } else { |
@@ -1390,6 +1402,7 @@ out: | |||
1390 | static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | 1402 | static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, |
1391 | struct nlattr **attrs) | 1403 | struct nlattr **attrs) |
1392 | { | 1404 | { |
1405 | struct net *net = sock_net(skb->sk); | ||
1393 | struct km_event c; | 1406 | struct km_event c; |
1394 | struct xfrm_usersa_flush *p = nlmsg_data(nlh); | 1407 | struct xfrm_usersa_flush *p = nlmsg_data(nlh); |
1395 | struct xfrm_audit audit_info; | 1408 | struct xfrm_audit audit_info; |
@@ -1398,13 +1411,14 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1398 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1411 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1399 | audit_info.sessionid = NETLINK_CB(skb).sessionid; | 1412 | audit_info.sessionid = NETLINK_CB(skb).sessionid; |
1400 | audit_info.secid = NETLINK_CB(skb).sid; | 1413 | audit_info.secid = NETLINK_CB(skb).sid; |
1401 | err = xfrm_state_flush(p->proto, &audit_info); | 1414 | err = xfrm_state_flush(net, p->proto, &audit_info); |
1402 | if (err) | 1415 | if (err) |
1403 | return err; | 1416 | return err; |
1404 | c.data.proto = p->proto; | 1417 | c.data.proto = p->proto; |
1405 | c.event = nlh->nlmsg_type; | 1418 | c.event = nlh->nlmsg_type; |
1406 | c.seq = nlh->nlmsg_seq; | 1419 | c.seq = nlh->nlmsg_seq; |
1407 | c.pid = nlh->nlmsg_pid; | 1420 | c.pid = nlh->nlmsg_pid; |
1421 | c.net = net; | ||
1408 | km_state_notify(NULL, &c); | 1422 | km_state_notify(NULL, &c); |
1409 | 1423 | ||
1410 | return 0; | 1424 | return 0; |
@@ -1457,6 +1471,7 @@ nla_put_failure: | |||
1457 | static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | 1471 | static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, |
1458 | struct nlattr **attrs) | 1472 | struct nlattr **attrs) |
1459 | { | 1473 | { |
1474 | struct net *net = sock_net(skb->sk); | ||
1460 | struct xfrm_state *x; | 1475 | struct xfrm_state *x; |
1461 | struct sk_buff *r_skb; | 1476 | struct sk_buff *r_skb; |
1462 | int err; | 1477 | int err; |
@@ -1468,7 +1483,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1468 | if (r_skb == NULL) | 1483 | if (r_skb == NULL) |
1469 | return -ENOMEM; | 1484 | return -ENOMEM; |
1470 | 1485 | ||
1471 | x = xfrm_state_lookup(&id->daddr, id->spi, id->proto, id->family); | 1486 | x = xfrm_state_lookup(net, &id->daddr, id->spi, id->proto, id->family); |
1472 | if (x == NULL) { | 1487 | if (x == NULL) { |
1473 | kfree_skb(r_skb); | 1488 | kfree_skb(r_skb); |
1474 | return -ESRCH; | 1489 | return -ESRCH; |
@@ -1486,7 +1501,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1486 | 1501 | ||
1487 | if (build_aevent(r_skb, x, &c) < 0) | 1502 | if (build_aevent(r_skb, x, &c) < 0) |
1488 | BUG(); | 1503 | BUG(); |
1489 | err = nlmsg_unicast(xfrm_nl, r_skb, NETLINK_CB(skb).pid); | 1504 | err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).pid); |
1490 | spin_unlock_bh(&x->lock); | 1505 | spin_unlock_bh(&x->lock); |
1491 | xfrm_state_put(x); | 1506 | xfrm_state_put(x); |
1492 | return err; | 1507 | return err; |
@@ -1495,6 +1510,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1495 | static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | 1510 | static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, |
1496 | struct nlattr **attrs) | 1511 | struct nlattr **attrs) |
1497 | { | 1512 | { |
1513 | struct net *net = sock_net(skb->sk); | ||
1498 | struct xfrm_state *x; | 1514 | struct xfrm_state *x; |
1499 | struct km_event c; | 1515 | struct km_event c; |
1500 | int err = - EINVAL; | 1516 | int err = - EINVAL; |
@@ -1509,7 +1525,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1509 | if (!(nlh->nlmsg_flags&NLM_F_REPLACE)) | 1525 | if (!(nlh->nlmsg_flags&NLM_F_REPLACE)) |
1510 | return err; | 1526 | return err; |
1511 | 1527 | ||
1512 | x = xfrm_state_lookup(&p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); | 1528 | x = xfrm_state_lookup(net, &p->sa_id.daddr, p->sa_id.spi, p->sa_id.proto, p->sa_id.family); |
1513 | if (x == NULL) | 1529 | if (x == NULL) |
1514 | return -ESRCH; | 1530 | return -ESRCH; |
1515 | 1531 | ||
@@ -1534,6 +1550,7 @@ out: | |||
1534 | static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | 1550 | static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, |
1535 | struct nlattr **attrs) | 1551 | struct nlattr **attrs) |
1536 | { | 1552 | { |
1553 | struct net *net = sock_net(skb->sk); | ||
1537 | struct km_event c; | 1554 | struct km_event c; |
1538 | u8 type = XFRM_POLICY_TYPE_MAIN; | 1555 | u8 type = XFRM_POLICY_TYPE_MAIN; |
1539 | int err; | 1556 | int err; |
@@ -1546,13 +1563,14 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1546 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1563 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1547 | audit_info.sessionid = NETLINK_CB(skb).sessionid; | 1564 | audit_info.sessionid = NETLINK_CB(skb).sessionid; |
1548 | audit_info.secid = NETLINK_CB(skb).sid; | 1565 | audit_info.secid = NETLINK_CB(skb).sid; |
1549 | err = xfrm_policy_flush(type, &audit_info); | 1566 | err = xfrm_policy_flush(net, type, &audit_info); |
1550 | if (err) | 1567 | if (err) |
1551 | return err; | 1568 | return err; |
1552 | c.data.type = type; | 1569 | c.data.type = type; |
1553 | c.event = nlh->nlmsg_type; | 1570 | c.event = nlh->nlmsg_type; |
1554 | c.seq = nlh->nlmsg_seq; | 1571 | c.seq = nlh->nlmsg_seq; |
1555 | c.pid = nlh->nlmsg_pid; | 1572 | c.pid = nlh->nlmsg_pid; |
1573 | c.net = net; | ||
1556 | km_policy_notify(NULL, 0, &c); | 1574 | km_policy_notify(NULL, 0, &c); |
1557 | return 0; | 1575 | return 0; |
1558 | } | 1576 | } |
@@ -1560,6 +1578,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1560 | static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | 1578 | static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, |
1561 | struct nlattr **attrs) | 1579 | struct nlattr **attrs) |
1562 | { | 1580 | { |
1581 | struct net *net = sock_net(skb->sk); | ||
1563 | struct xfrm_policy *xp; | 1582 | struct xfrm_policy *xp; |
1564 | struct xfrm_user_polexpire *up = nlmsg_data(nlh); | 1583 | struct xfrm_user_polexpire *up = nlmsg_data(nlh); |
1565 | struct xfrm_userpolicy_info *p = &up->pol; | 1584 | struct xfrm_userpolicy_info *p = &up->pol; |
@@ -1571,7 +1590,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1571 | return err; | 1590 | return err; |
1572 | 1591 | ||
1573 | if (p->index) | 1592 | if (p->index) |
1574 | xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err); | 1593 | xp = xfrm_policy_byid(net, type, p->dir, p->index, 0, &err); |
1575 | else { | 1594 | else { |
1576 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; | 1595 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; |
1577 | struct xfrm_sec_ctx *ctx; | 1596 | struct xfrm_sec_ctx *ctx; |
@@ -1588,7 +1607,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1588 | if (err) | 1607 | if (err) |
1589 | return err; | 1608 | return err; |
1590 | } | 1609 | } |
1591 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, ctx, 0, &err); | 1610 | xp = xfrm_policy_bysel_ctx(net, type, p->dir, &p->sel, ctx, 0, &err); |
1592 | security_xfrm_policy_free(ctx); | 1611 | security_xfrm_policy_free(ctx); |
1593 | } | 1612 | } |
1594 | if (xp == NULL) | 1613 | if (xp == NULL) |
@@ -1623,12 +1642,13 @@ out: | |||
1623 | static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | 1642 | static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, |
1624 | struct nlattr **attrs) | 1643 | struct nlattr **attrs) |
1625 | { | 1644 | { |
1645 | struct net *net = sock_net(skb->sk); | ||
1626 | struct xfrm_state *x; | 1646 | struct xfrm_state *x; |
1627 | int err; | 1647 | int err; |
1628 | struct xfrm_user_expire *ue = nlmsg_data(nlh); | 1648 | struct xfrm_user_expire *ue = nlmsg_data(nlh); |
1629 | struct xfrm_usersa_info *p = &ue->state; | 1649 | struct xfrm_usersa_info *p = &ue->state; |
1630 | 1650 | ||
1631 | x = xfrm_state_lookup(&p->id.daddr, p->id.spi, p->id.proto, p->family); | 1651 | x = xfrm_state_lookup(net, &p->id.daddr, p->id.spi, p->id.proto, p->family); |
1632 | 1652 | ||
1633 | err = -ENOENT; | 1653 | err = -ENOENT; |
1634 | if (x == NULL) | 1654 | if (x == NULL) |
@@ -1657,31 +1677,27 @@ out: | |||
1657 | static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, | 1677 | static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, |
1658 | struct nlattr **attrs) | 1678 | struct nlattr **attrs) |
1659 | { | 1679 | { |
1680 | struct net *net = sock_net(skb->sk); | ||
1660 | struct xfrm_policy *xp; | 1681 | struct xfrm_policy *xp; |
1661 | struct xfrm_user_tmpl *ut; | 1682 | struct xfrm_user_tmpl *ut; |
1662 | int i; | 1683 | int i; |
1663 | struct nlattr *rt = attrs[XFRMA_TMPL]; | 1684 | struct nlattr *rt = attrs[XFRMA_TMPL]; |
1664 | 1685 | ||
1665 | struct xfrm_user_acquire *ua = nlmsg_data(nlh); | 1686 | struct xfrm_user_acquire *ua = nlmsg_data(nlh); |
1666 | struct xfrm_state *x = xfrm_state_alloc(); | 1687 | struct xfrm_state *x = xfrm_state_alloc(net); |
1667 | int err = -ENOMEM; | 1688 | int err = -ENOMEM; |
1668 | 1689 | ||
1669 | if (!x) | 1690 | if (!x) |
1670 | return err; | 1691 | goto nomem; |
1671 | 1692 | ||
1672 | err = verify_newpolicy_info(&ua->policy); | 1693 | err = verify_newpolicy_info(&ua->policy); |
1673 | if (err) { | 1694 | if (err) |
1674 | printk("BAD policy passed\n"); | 1695 | goto bad_policy; |
1675 | kfree(x); | ||
1676 | return err; | ||
1677 | } | ||
1678 | 1696 | ||
1679 | /* build an XP */ | 1697 | /* build an XP */ |
1680 | xp = xfrm_policy_construct(&ua->policy, attrs, &err); | 1698 | xp = xfrm_policy_construct(net, &ua->policy, attrs, &err); |
1681 | if (!xp) { | 1699 | if (!xp) |
1682 | kfree(x); | 1700 | goto free_state; |
1683 | return err; | ||
1684 | } | ||
1685 | 1701 | ||
1686 | memcpy(&x->id, &ua->id, sizeof(ua->id)); | 1702 | memcpy(&x->id, &ua->id, sizeof(ua->id)); |
1687 | memcpy(&x->props.saddr, &ua->saddr, sizeof(ua->saddr)); | 1703 | memcpy(&x->props.saddr, &ua->saddr, sizeof(ua->saddr)); |
@@ -1706,6 +1722,13 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1706 | kfree(xp); | 1722 | kfree(xp); |
1707 | 1723 | ||
1708 | return 0; | 1724 | return 0; |
1725 | |||
1726 | bad_policy: | ||
1727 | printk("BAD policy passed\n"); | ||
1728 | free_state: | ||
1729 | kfree(x); | ||
1730 | nomem: | ||
1731 | return err; | ||
1709 | } | 1732 | } |
1710 | 1733 | ||
1711 | #ifdef CONFIG_XFRM_MIGRATE | 1734 | #ifdef CONFIG_XFRM_MIGRATE |
@@ -1869,6 +1892,7 @@ static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, | |||
1869 | struct xfrm_migrate *m, int num_migrate, | 1892 | struct xfrm_migrate *m, int num_migrate, |
1870 | struct xfrm_kmaddress *k) | 1893 | struct xfrm_kmaddress *k) |
1871 | { | 1894 | { |
1895 | struct net *net = &init_net; | ||
1872 | struct sk_buff *skb; | 1896 | struct sk_buff *skb; |
1873 | 1897 | ||
1874 | skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k), GFP_ATOMIC); | 1898 | skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k), GFP_ATOMIC); |
@@ -1879,7 +1903,7 @@ static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, | |||
1879 | if (build_migrate(skb, m, num_migrate, k, sel, dir, type) < 0) | 1903 | if (build_migrate(skb, m, num_migrate, k, sel, dir, type) < 0) |
1880 | BUG(); | 1904 | BUG(); |
1881 | 1905 | ||
1882 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MIGRATE, GFP_ATOMIC); | 1906 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_MIGRATE, GFP_ATOMIC); |
1883 | } | 1907 | } |
1884 | #else | 1908 | #else |
1885 | static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, | 1909 | static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, |
@@ -1968,6 +1992,7 @@ static struct xfrm_link { | |||
1968 | 1992 | ||
1969 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 1993 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
1970 | { | 1994 | { |
1995 | struct net *net = sock_net(skb->sk); | ||
1971 | struct nlattr *attrs[XFRMA_MAX+1]; | 1996 | struct nlattr *attrs[XFRMA_MAX+1]; |
1972 | struct xfrm_link *link; | 1997 | struct xfrm_link *link; |
1973 | int type, err; | 1998 | int type, err; |
@@ -1989,7 +2014,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1989 | if (link->dump == NULL) | 2014 | if (link->dump == NULL) |
1990 | return -EINVAL; | 2015 | return -EINVAL; |
1991 | 2016 | ||
1992 | return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, link->done); | 2017 | return netlink_dump_start(net->xfrm.nlsk, skb, nlh, link->dump, link->done); |
1993 | } | 2018 | } |
1994 | 2019 | ||
1995 | err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX, | 2020 | err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX, |
@@ -2033,6 +2058,7 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_eve | |||
2033 | 2058 | ||
2034 | static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) | 2059 | static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) |
2035 | { | 2060 | { |
2061 | struct net *net = xs_net(x); | ||
2036 | struct sk_buff *skb; | 2062 | struct sk_buff *skb; |
2037 | 2063 | ||
2038 | skb = nlmsg_new(xfrm_expire_msgsize(), GFP_ATOMIC); | 2064 | skb = nlmsg_new(xfrm_expire_msgsize(), GFP_ATOMIC); |
@@ -2042,11 +2068,12 @@ static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c) | |||
2042 | if (build_expire(skb, x, c) < 0) | 2068 | if (build_expire(skb, x, c) < 0) |
2043 | BUG(); | 2069 | BUG(); |
2044 | 2070 | ||
2045 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); | 2071 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); |
2046 | } | 2072 | } |
2047 | 2073 | ||
2048 | static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c) | 2074 | static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c) |
2049 | { | 2075 | { |
2076 | struct net *net = xs_net(x); | ||
2050 | struct sk_buff *skb; | 2077 | struct sk_buff *skb; |
2051 | 2078 | ||
2052 | skb = nlmsg_new(xfrm_aevent_msgsize(), GFP_ATOMIC); | 2079 | skb = nlmsg_new(xfrm_aevent_msgsize(), GFP_ATOMIC); |
@@ -2056,11 +2083,12 @@ static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c) | |||
2056 | if (build_aevent(skb, x, c) < 0) | 2083 | if (build_aevent(skb, x, c) < 0) |
2057 | BUG(); | 2084 | BUG(); |
2058 | 2085 | ||
2059 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_AEVENTS, GFP_ATOMIC); | 2086 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_AEVENTS, GFP_ATOMIC); |
2060 | } | 2087 | } |
2061 | 2088 | ||
2062 | static int xfrm_notify_sa_flush(struct km_event *c) | 2089 | static int xfrm_notify_sa_flush(struct km_event *c) |
2063 | { | 2090 | { |
2091 | struct net *net = c->net; | ||
2064 | struct xfrm_usersa_flush *p; | 2092 | struct xfrm_usersa_flush *p; |
2065 | struct nlmsghdr *nlh; | 2093 | struct nlmsghdr *nlh; |
2066 | struct sk_buff *skb; | 2094 | struct sk_buff *skb; |
@@ -2081,7 +2109,7 @@ static int xfrm_notify_sa_flush(struct km_event *c) | |||
2081 | 2109 | ||
2082 | nlmsg_end(skb, nlh); | 2110 | nlmsg_end(skb, nlh); |
2083 | 2111 | ||
2084 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); | 2112 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); |
2085 | } | 2113 | } |
2086 | 2114 | ||
2087 | static inline size_t xfrm_sa_len(struct xfrm_state *x) | 2115 | static inline size_t xfrm_sa_len(struct xfrm_state *x) |
@@ -2111,6 +2139,7 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x) | |||
2111 | 2139 | ||
2112 | static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c) | 2140 | static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c) |
2113 | { | 2141 | { |
2142 | struct net *net = xs_net(x); | ||
2114 | struct xfrm_usersa_info *p; | 2143 | struct xfrm_usersa_info *p; |
2115 | struct xfrm_usersa_id *id; | 2144 | struct xfrm_usersa_id *id; |
2116 | struct nlmsghdr *nlh; | 2145 | struct nlmsghdr *nlh; |
@@ -2155,7 +2184,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c) | |||
2155 | 2184 | ||
2156 | nlmsg_end(skb, nlh); | 2185 | nlmsg_end(skb, nlh); |
2157 | 2186 | ||
2158 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); | 2187 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC); |
2159 | 2188 | ||
2160 | nla_put_failure: | 2189 | nla_put_failure: |
2161 | /* Somebody screwed up with xfrm_sa_len! */ | 2190 | /* Somebody screwed up with xfrm_sa_len! */ |
@@ -2235,6 +2264,7 @@ nlmsg_failure: | |||
2235 | static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, | 2264 | static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, |
2236 | struct xfrm_policy *xp, int dir) | 2265 | struct xfrm_policy *xp, int dir) |
2237 | { | 2266 | { |
2267 | struct net *net = xs_net(x); | ||
2238 | struct sk_buff *skb; | 2268 | struct sk_buff *skb; |
2239 | 2269 | ||
2240 | skb = nlmsg_new(xfrm_acquire_msgsize(x, xp), GFP_ATOMIC); | 2270 | skb = nlmsg_new(xfrm_acquire_msgsize(x, xp), GFP_ATOMIC); |
@@ -2244,7 +2274,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, | |||
2244 | if (build_acquire(skb, x, xt, xp, dir) < 0) | 2274 | if (build_acquire(skb, x, xt, xp, dir) < 0) |
2245 | BUG(); | 2275 | BUG(); |
2246 | 2276 | ||
2247 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_ACQUIRE, GFP_ATOMIC); | 2277 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_ACQUIRE, GFP_ATOMIC); |
2248 | } | 2278 | } |
2249 | 2279 | ||
2250 | /* User gives us xfrm_user_policy_info followed by an array of 0 | 2280 | /* User gives us xfrm_user_policy_info followed by an array of 0 |
@@ -2253,6 +2283,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, | |||
2253 | static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt, | 2283 | static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt, |
2254 | u8 *data, int len, int *dir) | 2284 | u8 *data, int len, int *dir) |
2255 | { | 2285 | { |
2286 | struct net *net = sock_net(sk); | ||
2256 | struct xfrm_userpolicy_info *p = (struct xfrm_userpolicy_info *)data; | 2287 | struct xfrm_userpolicy_info *p = (struct xfrm_userpolicy_info *)data; |
2257 | struct xfrm_user_tmpl *ut = (struct xfrm_user_tmpl *) (p + 1); | 2288 | struct xfrm_user_tmpl *ut = (struct xfrm_user_tmpl *) (p + 1); |
2258 | struct xfrm_policy *xp; | 2289 | struct xfrm_policy *xp; |
@@ -2291,7 +2322,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt, | |||
2291 | if (p->dir > XFRM_POLICY_OUT) | 2322 | if (p->dir > XFRM_POLICY_OUT) |
2292 | return NULL; | 2323 | return NULL; |
2293 | 2324 | ||
2294 | xp = xfrm_policy_alloc(GFP_KERNEL); | 2325 | xp = xfrm_policy_alloc(net, GFP_KERNEL); |
2295 | if (xp == NULL) { | 2326 | if (xp == NULL) { |
2296 | *dir = -ENOBUFS; | 2327 | *dir = -ENOBUFS; |
2297 | return NULL; | 2328 | return NULL; |
@@ -2344,6 +2375,7 @@ nlmsg_failure: | |||
2344 | 2375 | ||
2345 | static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c) | 2376 | static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c) |
2346 | { | 2377 | { |
2378 | struct net *net = xp_net(xp); | ||
2347 | struct sk_buff *skb; | 2379 | struct sk_buff *skb; |
2348 | 2380 | ||
2349 | skb = nlmsg_new(xfrm_polexpire_msgsize(xp), GFP_ATOMIC); | 2381 | skb = nlmsg_new(xfrm_polexpire_msgsize(xp), GFP_ATOMIC); |
@@ -2353,11 +2385,12 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve | |||
2353 | if (build_polexpire(skb, xp, dir, c) < 0) | 2385 | if (build_polexpire(skb, xp, dir, c) < 0) |
2354 | BUG(); | 2386 | BUG(); |
2355 | 2387 | ||
2356 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); | 2388 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC); |
2357 | } | 2389 | } |
2358 | 2390 | ||
2359 | static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c) | 2391 | static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c) |
2360 | { | 2392 | { |
2393 | struct net *net = xp_net(xp); | ||
2361 | struct xfrm_userpolicy_info *p; | 2394 | struct xfrm_userpolicy_info *p; |
2362 | struct xfrm_userpolicy_id *id; | 2395 | struct xfrm_userpolicy_id *id; |
2363 | struct nlmsghdr *nlh; | 2396 | struct nlmsghdr *nlh; |
@@ -2408,7 +2441,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * | |||
2408 | 2441 | ||
2409 | nlmsg_end(skb, nlh); | 2442 | nlmsg_end(skb, nlh); |
2410 | 2443 | ||
2411 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); | 2444 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); |
2412 | 2445 | ||
2413 | nlmsg_failure: | 2446 | nlmsg_failure: |
2414 | kfree_skb(skb); | 2447 | kfree_skb(skb); |
@@ -2417,6 +2450,7 @@ nlmsg_failure: | |||
2417 | 2450 | ||
2418 | static int xfrm_notify_policy_flush(struct km_event *c) | 2451 | static int xfrm_notify_policy_flush(struct km_event *c) |
2419 | { | 2452 | { |
2453 | struct net *net = c->net; | ||
2420 | struct nlmsghdr *nlh; | 2454 | struct nlmsghdr *nlh; |
2421 | struct sk_buff *skb; | 2455 | struct sk_buff *skb; |
2422 | 2456 | ||
@@ -2432,7 +2466,7 @@ static int xfrm_notify_policy_flush(struct km_event *c) | |||
2432 | 2466 | ||
2433 | nlmsg_end(skb, nlh); | 2467 | nlmsg_end(skb, nlh); |
2434 | 2468 | ||
2435 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); | 2469 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); |
2436 | 2470 | ||
2437 | nlmsg_failure: | 2471 | nlmsg_failure: |
2438 | kfree_skb(skb); | 2472 | kfree_skb(skb); |
@@ -2488,8 +2522,8 @@ nla_put_failure: | |||
2488 | return -EMSGSIZE; | 2522 | return -EMSGSIZE; |
2489 | } | 2523 | } |
2490 | 2524 | ||
2491 | static int xfrm_send_report(u8 proto, struct xfrm_selector *sel, | 2525 | static int xfrm_send_report(struct net *net, u8 proto, |
2492 | xfrm_address_t *addr) | 2526 | struct xfrm_selector *sel, xfrm_address_t *addr) |
2493 | { | 2527 | { |
2494 | struct sk_buff *skb; | 2528 | struct sk_buff *skb; |
2495 | 2529 | ||
@@ -2500,7 +2534,59 @@ static int xfrm_send_report(u8 proto, struct xfrm_selector *sel, | |||
2500 | if (build_report(skb, proto, sel, addr) < 0) | 2534 | if (build_report(skb, proto, sel, addr) < 0) |
2501 | BUG(); | 2535 | BUG(); |
2502 | 2536 | ||
2503 | return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_REPORT, GFP_ATOMIC); | 2537 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_REPORT, GFP_ATOMIC); |
2538 | } | ||
2539 | |||
2540 | static inline size_t xfrm_mapping_msgsize(void) | ||
2541 | { | ||
2542 | return NLMSG_ALIGN(sizeof(struct xfrm_user_mapping)); | ||
2543 | } | ||
2544 | |||
2545 | static int build_mapping(struct sk_buff *skb, struct xfrm_state *x, | ||
2546 | xfrm_address_t *new_saddr, __be16 new_sport) | ||
2547 | { | ||
2548 | struct xfrm_user_mapping *um; | ||
2549 | struct nlmsghdr *nlh; | ||
2550 | |||
2551 | nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_MAPPING, sizeof(*um), 0); | ||
2552 | if (nlh == NULL) | ||
2553 | return -EMSGSIZE; | ||
2554 | |||
2555 | um = nlmsg_data(nlh); | ||
2556 | |||
2557 | memcpy(&um->id.daddr, &x->id.daddr, sizeof(um->id.daddr)); | ||
2558 | um->id.spi = x->id.spi; | ||
2559 | um->id.family = x->props.family; | ||
2560 | um->id.proto = x->id.proto; | ||
2561 | memcpy(&um->new_saddr, new_saddr, sizeof(um->new_saddr)); | ||
2562 | memcpy(&um->old_saddr, &x->props.saddr, sizeof(um->old_saddr)); | ||
2563 | um->new_sport = new_sport; | ||
2564 | um->old_sport = x->encap->encap_sport; | ||
2565 | um->reqid = x->props.reqid; | ||
2566 | |||
2567 | return nlmsg_end(skb, nlh); | ||
2568 | } | ||
2569 | |||
2570 | static int xfrm_send_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, | ||
2571 | __be16 sport) | ||
2572 | { | ||
2573 | struct net *net = xs_net(x); | ||
2574 | struct sk_buff *skb; | ||
2575 | |||
2576 | if (x->id.proto != IPPROTO_ESP) | ||
2577 | return -EINVAL; | ||
2578 | |||
2579 | if (!x->encap) | ||
2580 | return -EINVAL; | ||
2581 | |||
2582 | skb = nlmsg_new(xfrm_mapping_msgsize(), GFP_ATOMIC); | ||
2583 | if (skb == NULL) | ||
2584 | return -ENOMEM; | ||
2585 | |||
2586 | if (build_mapping(skb, x, ipaddr, sport) < 0) | ||
2587 | BUG(); | ||
2588 | |||
2589 | return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_MAPPING, GFP_ATOMIC); | ||
2504 | } | 2590 | } |
2505 | 2591 | ||
2506 | static struct xfrm_mgr netlink_mgr = { | 2592 | static struct xfrm_mgr netlink_mgr = { |
@@ -2511,35 +2597,56 @@ static struct xfrm_mgr netlink_mgr = { | |||
2511 | .notify_policy = xfrm_send_policy_notify, | 2597 | .notify_policy = xfrm_send_policy_notify, |
2512 | .report = xfrm_send_report, | 2598 | .report = xfrm_send_report, |
2513 | .migrate = xfrm_send_migrate, | 2599 | .migrate = xfrm_send_migrate, |
2600 | .new_mapping = xfrm_send_mapping, | ||
2514 | }; | 2601 | }; |
2515 | 2602 | ||
2516 | static int __init xfrm_user_init(void) | 2603 | static int __net_init xfrm_user_net_init(struct net *net) |
2517 | { | 2604 | { |
2518 | struct sock *nlsk; | 2605 | struct sock *nlsk; |
2519 | 2606 | ||
2520 | printk(KERN_INFO "Initializing XFRM netlink socket\n"); | 2607 | nlsk = netlink_kernel_create(net, NETLINK_XFRM, XFRMNLGRP_MAX, |
2521 | |||
2522 | nlsk = netlink_kernel_create(&init_net, NETLINK_XFRM, XFRMNLGRP_MAX, | ||
2523 | xfrm_netlink_rcv, NULL, THIS_MODULE); | 2608 | xfrm_netlink_rcv, NULL, THIS_MODULE); |
2524 | if (nlsk == NULL) | 2609 | if (nlsk == NULL) |
2525 | return -ENOMEM; | 2610 | return -ENOMEM; |
2526 | rcu_assign_pointer(xfrm_nl, nlsk); | 2611 | rcu_assign_pointer(net->xfrm.nlsk, nlsk); |
2527 | |||
2528 | xfrm_register_km(&netlink_mgr); | ||
2529 | |||
2530 | return 0; | 2612 | return 0; |
2531 | } | 2613 | } |
2532 | 2614 | ||
2533 | static void __exit xfrm_user_exit(void) | 2615 | static void __net_exit xfrm_user_net_exit(struct net *net) |
2534 | { | 2616 | { |
2535 | struct sock *nlsk = xfrm_nl; | 2617 | struct sock *nlsk = net->xfrm.nlsk; |
2536 | 2618 | ||
2537 | xfrm_unregister_km(&netlink_mgr); | 2619 | rcu_assign_pointer(net->xfrm.nlsk, NULL); |
2538 | rcu_assign_pointer(xfrm_nl, NULL); | ||
2539 | synchronize_rcu(); | 2620 | synchronize_rcu(); |
2540 | netlink_kernel_release(nlsk); | 2621 | netlink_kernel_release(nlsk); |
2541 | } | 2622 | } |
2542 | 2623 | ||
2624 | static struct pernet_operations xfrm_user_net_ops = { | ||
2625 | .init = xfrm_user_net_init, | ||
2626 | .exit = xfrm_user_net_exit, | ||
2627 | }; | ||
2628 | |||
2629 | static int __init xfrm_user_init(void) | ||
2630 | { | ||
2631 | int rv; | ||
2632 | |||
2633 | printk(KERN_INFO "Initializing XFRM netlink socket\n"); | ||
2634 | |||
2635 | rv = register_pernet_subsys(&xfrm_user_net_ops); | ||
2636 | if (rv < 0) | ||
2637 | return rv; | ||
2638 | rv = xfrm_register_km(&netlink_mgr); | ||
2639 | if (rv < 0) | ||
2640 | unregister_pernet_subsys(&xfrm_user_net_ops); | ||
2641 | return rv; | ||
2642 | } | ||
2643 | |||
2644 | static void __exit xfrm_user_exit(void) | ||
2645 | { | ||
2646 | xfrm_unregister_km(&netlink_mgr); | ||
2647 | unregister_pernet_subsys(&xfrm_user_net_ops); | ||
2648 | } | ||
2649 | |||
2543 | module_init(xfrm_user_init); | 2650 | module_init(xfrm_user_init); |
2544 | module_exit(xfrm_user_exit); | 2651 | module_exit(xfrm_user_exit); |
2545 | MODULE_LICENSE("GPL"); | 2652 | MODULE_LICENSE("GPL"); |