diff options
Diffstat (limited to 'net/key/af_key.c')
-rw-r--r-- | net/key/af_key.c | 589 |
1 files changed, 506 insertions, 83 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c index 5dd5094659a1..1c58204d767e 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -152,7 +152,7 @@ static int pfkey_create(struct socket *sock, int protocol) | |||
152 | sk = sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1); | 152 | sk = sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1); |
153 | if (sk == NULL) | 153 | if (sk == NULL) |
154 | goto out; | 154 | goto out; |
155 | 155 | ||
156 | sock->ops = &pfkey_ops; | 156 | sock->ops = &pfkey_ops; |
157 | sock_init_data(sock, sk); | 157 | sock_init_data(sock, sk); |
158 | 158 | ||
@@ -487,7 +487,7 @@ static int parse_exthdrs(struct sk_buff *skb, struct sadb_msg *hdr, void **ext_h | |||
487 | ext_type == SADB_X_EXT_NAT_T_OA) { | 487 | ext_type == SADB_X_EXT_NAT_T_OA) { |
488 | if (verify_address_len(p)) | 488 | if (verify_address_len(p)) |
489 | return -EINVAL; | 489 | return -EINVAL; |
490 | } | 490 | } |
491 | if (ext_type == SADB_X_EXT_SEC_CTX) { | 491 | if (ext_type == SADB_X_EXT_SEC_CTX) { |
492 | if (verify_sec_ctx_len(p)) | 492 | if (verify_sec_ctx_len(p)) |
493 | return -EINVAL; | 493 | return -EINVAL; |
@@ -556,12 +556,12 @@ static int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, | |||
556 | { | 556 | { |
557 | switch (((struct sockaddr*)(addr + 1))->sa_family) { | 557 | switch (((struct sockaddr*)(addr + 1))->sa_family) { |
558 | case AF_INET: | 558 | case AF_INET: |
559 | xaddr->a4 = | 559 | xaddr->a4 = |
560 | ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr; | 560 | ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr; |
561 | return AF_INET; | 561 | return AF_INET; |
562 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 562 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
563 | case AF_INET6: | 563 | case AF_INET6: |
564 | memcpy(xaddr->a6, | 564 | memcpy(xaddr->a6, |
565 | &((struct sockaddr_in6 *)(addr + 1))->sin6_addr, | 565 | &((struct sockaddr_in6 *)(addr + 1))->sin6_addr, |
566 | sizeof(struct in6_addr)); | 566 | sizeof(struct in6_addr)); |
567 | return AF_INET6; | 567 | return AF_INET6; |
@@ -659,11 +659,11 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
659 | 659 | ||
660 | /* base, SA, (lifetime (HSC),) address(SD), (address(P),) | 660 | /* base, SA, (lifetime (HSC),) address(SD), (address(P),) |
661 | key(AE), (identity(SD),) (sensitivity)> */ | 661 | key(AE), (identity(SD),) (sensitivity)> */ |
662 | size = sizeof(struct sadb_msg) +sizeof(struct sadb_sa) + | 662 | size = sizeof(struct sadb_msg) +sizeof(struct sadb_sa) + |
663 | sizeof(struct sadb_lifetime) + | 663 | sizeof(struct sadb_lifetime) + |
664 | ((hsc & 1) ? sizeof(struct sadb_lifetime) : 0) + | 664 | ((hsc & 1) ? sizeof(struct sadb_lifetime) : 0) + |
665 | ((hsc & 2) ? sizeof(struct sadb_lifetime) : 0) + | 665 | ((hsc & 2) ? sizeof(struct sadb_lifetime) : 0) + |
666 | sizeof(struct sadb_address)*2 + | 666 | sizeof(struct sadb_address)*2 + |
667 | sockaddr_size*2 + | 667 | sockaddr_size*2 + |
668 | sizeof(struct sadb_x_sa2); | 668 | sizeof(struct sadb_x_sa2); |
669 | 669 | ||
@@ -685,13 +685,13 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
685 | 685 | ||
686 | if (add_keys) { | 686 | if (add_keys) { |
687 | if (x->aalg && x->aalg->alg_key_len) { | 687 | if (x->aalg && x->aalg->alg_key_len) { |
688 | auth_key_size = | 688 | auth_key_size = |
689 | PFKEY_ALIGN8((x->aalg->alg_key_len + 7) / 8); | 689 | PFKEY_ALIGN8((x->aalg->alg_key_len + 7) / 8); |
690 | size += sizeof(struct sadb_key) + auth_key_size; | 690 | size += sizeof(struct sadb_key) + auth_key_size; |
691 | } | 691 | } |
692 | if (x->ealg && x->ealg->alg_key_len) { | 692 | if (x->ealg && x->ealg->alg_key_len) { |
693 | encrypt_key_size = | 693 | encrypt_key_size = |
694 | PFKEY_ALIGN8((x->ealg->alg_key_len+7) / 8); | 694 | PFKEY_ALIGN8((x->ealg->alg_key_len+7) / 8); |
695 | size += sizeof(struct sadb_key) + encrypt_key_size; | 695 | size += sizeof(struct sadb_key) + encrypt_key_size; |
696 | } | 696 | } |
697 | } | 697 | } |
@@ -758,7 +758,7 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
758 | 758 | ||
759 | /* hard time */ | 759 | /* hard time */ |
760 | if (hsc & 2) { | 760 | if (hsc & 2) { |
761 | lifetime = (struct sadb_lifetime *) skb_put(skb, | 761 | lifetime = (struct sadb_lifetime *) skb_put(skb, |
762 | sizeof(struct sadb_lifetime)); | 762 | sizeof(struct sadb_lifetime)); |
763 | lifetime->sadb_lifetime_len = | 763 | lifetime->sadb_lifetime_len = |
764 | sizeof(struct sadb_lifetime)/sizeof(uint64_t); | 764 | sizeof(struct sadb_lifetime)/sizeof(uint64_t); |
@@ -770,7 +770,7 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
770 | } | 770 | } |
771 | /* soft time */ | 771 | /* soft time */ |
772 | if (hsc & 1) { | 772 | if (hsc & 1) { |
773 | lifetime = (struct sadb_lifetime *) skb_put(skb, | 773 | lifetime = (struct sadb_lifetime *) skb_put(skb, |
774 | sizeof(struct sadb_lifetime)); | 774 | sizeof(struct sadb_lifetime)); |
775 | lifetime->sadb_lifetime_len = | 775 | lifetime->sadb_lifetime_len = |
776 | sizeof(struct sadb_lifetime)/sizeof(uint64_t); | 776 | sizeof(struct sadb_lifetime)/sizeof(uint64_t); |
@@ -791,16 +791,16 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
791 | lifetime->sadb_lifetime_addtime = x->curlft.add_time; | 791 | lifetime->sadb_lifetime_addtime = x->curlft.add_time; |
792 | lifetime->sadb_lifetime_usetime = x->curlft.use_time; | 792 | lifetime->sadb_lifetime_usetime = x->curlft.use_time; |
793 | /* src address */ | 793 | /* src address */ |
794 | addr = (struct sadb_address*) skb_put(skb, | 794 | addr = (struct sadb_address*) skb_put(skb, |
795 | sizeof(struct sadb_address)+sockaddr_size); | 795 | sizeof(struct sadb_address)+sockaddr_size); |
796 | addr->sadb_address_len = | 796 | addr->sadb_address_len = |
797 | (sizeof(struct sadb_address)+sockaddr_size)/ | 797 | (sizeof(struct sadb_address)+sockaddr_size)/ |
798 | sizeof(uint64_t); | 798 | sizeof(uint64_t); |
799 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; | 799 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; |
800 | /* "if the ports are non-zero, then the sadb_address_proto field, | 800 | /* "if the ports are non-zero, then the sadb_address_proto field, |
801 | normally zero, MUST be filled in with the transport | 801 | normally zero, MUST be filled in with the transport |
802 | protocol's number." - RFC2367 */ | 802 | protocol's number." - RFC2367 */ |
803 | addr->sadb_address_proto = 0; | 803 | addr->sadb_address_proto = 0; |
804 | addr->sadb_address_reserved = 0; | 804 | addr->sadb_address_reserved = 0; |
805 | if (x->props.family == AF_INET) { | 805 | if (x->props.family == AF_INET) { |
806 | addr->sadb_address_prefixlen = 32; | 806 | addr->sadb_address_prefixlen = 32; |
@@ -813,29 +813,29 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
813 | } | 813 | } |
814 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 814 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
815 | else if (x->props.family == AF_INET6) { | 815 | else if (x->props.family == AF_INET6) { |
816 | addr->sadb_address_prefixlen = 128; | 816 | addr->sadb_address_prefixlen = 128; |
817 | 817 | ||
818 | sin6 = (struct sockaddr_in6 *) (addr + 1); | 818 | sin6 = (struct sockaddr_in6 *) (addr + 1); |
819 | sin6->sin6_family = AF_INET6; | 819 | sin6->sin6_family = AF_INET6; |
820 | sin6->sin6_port = 0; | 820 | sin6->sin6_port = 0; |
821 | sin6->sin6_flowinfo = 0; | 821 | sin6->sin6_flowinfo = 0; |
822 | memcpy(&sin6->sin6_addr, x->props.saddr.a6, | 822 | memcpy(&sin6->sin6_addr, x->props.saddr.a6, |
823 | sizeof(struct in6_addr)); | 823 | sizeof(struct in6_addr)); |
824 | sin6->sin6_scope_id = 0; | 824 | sin6->sin6_scope_id = 0; |
825 | } | 825 | } |
826 | #endif | 826 | #endif |
827 | else | 827 | else |
828 | BUG(); | 828 | BUG(); |
829 | 829 | ||
830 | /* dst address */ | 830 | /* dst address */ |
831 | addr = (struct sadb_address*) skb_put(skb, | 831 | addr = (struct sadb_address*) skb_put(skb, |
832 | sizeof(struct sadb_address)+sockaddr_size); | 832 | sizeof(struct sadb_address)+sockaddr_size); |
833 | addr->sadb_address_len = | 833 | addr->sadb_address_len = |
834 | (sizeof(struct sadb_address)+sockaddr_size)/ | 834 | (sizeof(struct sadb_address)+sockaddr_size)/ |
835 | sizeof(uint64_t); | 835 | sizeof(uint64_t); |
836 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; | 836 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; |
837 | addr->sadb_address_proto = 0; | 837 | addr->sadb_address_proto = 0; |
838 | addr->sadb_address_prefixlen = 32; /* XXX */ | 838 | addr->sadb_address_prefixlen = 32; /* XXX */ |
839 | addr->sadb_address_reserved = 0; | 839 | addr->sadb_address_reserved = 0; |
840 | if (x->props.family == AF_INET) { | 840 | if (x->props.family == AF_INET) { |
841 | sin = (struct sockaddr_in *) (addr + 1); | 841 | sin = (struct sockaddr_in *) (addr + 1); |
@@ -845,9 +845,9 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
845 | memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); | 845 | memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); |
846 | 846 | ||
847 | if (x->sel.saddr.a4 != x->props.saddr.a4) { | 847 | if (x->sel.saddr.a4 != x->props.saddr.a4) { |
848 | addr = (struct sadb_address*) skb_put(skb, | 848 | addr = (struct sadb_address*) skb_put(skb, |
849 | sizeof(struct sadb_address)+sockaddr_size); | 849 | sizeof(struct sadb_address)+sockaddr_size); |
850 | addr->sadb_address_len = | 850 | addr->sadb_address_len = |
851 | (sizeof(struct sadb_address)+sockaddr_size)/ | 851 | (sizeof(struct sadb_address)+sockaddr_size)/ |
852 | sizeof(uint64_t); | 852 | sizeof(uint64_t); |
853 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; | 853 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; |
@@ -876,9 +876,9 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
876 | 876 | ||
877 | if (memcmp (x->sel.saddr.a6, x->props.saddr.a6, | 877 | if (memcmp (x->sel.saddr.a6, x->props.saddr.a6, |
878 | sizeof(struct in6_addr))) { | 878 | sizeof(struct in6_addr))) { |
879 | addr = (struct sadb_address *) skb_put(skb, | 879 | addr = (struct sadb_address *) skb_put(skb, |
880 | sizeof(struct sadb_address)+sockaddr_size); | 880 | sizeof(struct sadb_address)+sockaddr_size); |
881 | addr->sadb_address_len = | 881 | addr->sadb_address_len = |
882 | (sizeof(struct sadb_address)+sockaddr_size)/ | 882 | (sizeof(struct sadb_address)+sockaddr_size)/ |
883 | sizeof(uint64_t); | 883 | sizeof(uint64_t); |
884 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; | 884 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; |
@@ -902,7 +902,7 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
902 | 902 | ||
903 | /* auth key */ | 903 | /* auth key */ |
904 | if (add_keys && auth_key_size) { | 904 | if (add_keys && auth_key_size) { |
905 | key = (struct sadb_key *) skb_put(skb, | 905 | key = (struct sadb_key *) skb_put(skb, |
906 | sizeof(struct sadb_key)+auth_key_size); | 906 | sizeof(struct sadb_key)+auth_key_size); |
907 | key->sadb_key_len = (sizeof(struct sadb_key) + auth_key_size) / | 907 | key->sadb_key_len = (sizeof(struct sadb_key) + auth_key_size) / |
908 | sizeof(uint64_t); | 908 | sizeof(uint64_t); |
@@ -913,14 +913,14 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
913 | } | 913 | } |
914 | /* encrypt key */ | 914 | /* encrypt key */ |
915 | if (add_keys && encrypt_key_size) { | 915 | if (add_keys && encrypt_key_size) { |
916 | key = (struct sadb_key *) skb_put(skb, | 916 | key = (struct sadb_key *) skb_put(skb, |
917 | sizeof(struct sadb_key)+encrypt_key_size); | 917 | sizeof(struct sadb_key)+encrypt_key_size); |
918 | key->sadb_key_len = (sizeof(struct sadb_key) + | 918 | key->sadb_key_len = (sizeof(struct sadb_key) + |
919 | encrypt_key_size) / sizeof(uint64_t); | 919 | encrypt_key_size) / sizeof(uint64_t); |
920 | key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; | 920 | key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; |
921 | key->sadb_key_bits = x->ealg->alg_key_len; | 921 | key->sadb_key_bits = x->ealg->alg_key_len; |
922 | key->sadb_key_reserved = 0; | 922 | key->sadb_key_reserved = 0; |
923 | memcpy(key + 1, x->ealg->alg_key, | 923 | memcpy(key + 1, x->ealg->alg_key, |
924 | (x->ealg->alg_key_len+7)/8); | 924 | (x->ealg->alg_key_len+7)/8); |
925 | } | 925 | } |
926 | 926 | ||
@@ -979,17 +979,17 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
979 | return skb; | 979 | return skb; |
980 | } | 980 | } |
981 | 981 | ||
982 | static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, | 982 | static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, |
983 | void **ext_hdrs) | 983 | void **ext_hdrs) |
984 | { | 984 | { |
985 | struct xfrm_state *x; | 985 | struct xfrm_state *x; |
986 | struct sadb_lifetime *lifetime; | 986 | struct sadb_lifetime *lifetime; |
987 | struct sadb_sa *sa; | 987 | struct sadb_sa *sa; |
988 | struct sadb_key *key; | 988 | struct sadb_key *key; |
989 | struct sadb_x_sec_ctx *sec_ctx; | 989 | struct sadb_x_sec_ctx *sec_ctx; |
990 | uint16_t proto; | 990 | uint16_t proto; |
991 | int err; | 991 | int err; |
992 | 992 | ||
993 | 993 | ||
994 | sa = (struct sadb_sa *) ext_hdrs[SADB_EXT_SA-1]; | 994 | sa = (struct sadb_sa *) ext_hdrs[SADB_EXT_SA-1]; |
995 | if (!sa || | 995 | if (!sa || |
@@ -1022,7 +1022,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, | |||
1022 | SADB_SASTATE_MATURE and the kernel MUST return an error if this is | 1022 | SADB_SASTATE_MATURE and the kernel MUST return an error if this is |
1023 | not true. | 1023 | not true. |
1024 | 1024 | ||
1025 | However, KAME setkey always uses SADB_SASTATE_LARVAL. | 1025 | However, KAME setkey always uses SADB_SASTATE_LARVAL. |
1026 | Hence, we have to _ignore_ sadb_sa_state, which is also reasonable. | 1026 | Hence, we have to _ignore_ sadb_sa_state, which is also reasonable. |
1027 | */ | 1027 | */ |
1028 | if (sa->sadb_sa_auth > SADB_AALG_MAX || | 1028 | if (sa->sadb_sa_auth > SADB_AALG_MAX || |
@@ -1144,13 +1144,13 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, | |||
1144 | } | 1144 | } |
1145 | /* x->algo.flags = sa->sadb_sa_flags; */ | 1145 | /* x->algo.flags = sa->sadb_sa_flags; */ |
1146 | 1146 | ||
1147 | x->props.family = pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_SRC-1], | 1147 | x->props.family = pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_SRC-1], |
1148 | &x->props.saddr); | 1148 | &x->props.saddr); |
1149 | if (!x->props.family) { | 1149 | if (!x->props.family) { |
1150 | err = -EAFNOSUPPORT; | 1150 | err = -EAFNOSUPPORT; |
1151 | goto out; | 1151 | goto out; |
1152 | } | 1152 | } |
1153 | pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_DST-1], | 1153 | pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_DST-1], |
1154 | &x->id.daddr); | 1154 | &x->id.daddr); |
1155 | 1155 | ||
1156 | if (ext_hdrs[SADB_X_EXT_SA2-1]) { | 1156 | if (ext_hdrs[SADB_X_EXT_SA2-1]) { |
@@ -1410,7 +1410,7 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, | |||
1410 | struct km_event c; | 1410 | struct km_event c; |
1411 | 1411 | ||
1412 | xfrm_probe_algs(); | 1412 | xfrm_probe_algs(); |
1413 | 1413 | ||
1414 | x = pfkey_msg2xfrm_state(hdr, ext_hdrs); | 1414 | x = pfkey_msg2xfrm_state(hdr, ext_hdrs); |
1415 | if (IS_ERR(x)) | 1415 | if (IS_ERR(x)) |
1416 | return PTR_ERR(x); | 1416 | return PTR_ERR(x); |
@@ -1530,13 +1530,13 @@ static struct sk_buff *compose_sadb_supported(struct sadb_msg *orig, | |||
1530 | auth_len *= sizeof(struct sadb_alg); | 1530 | auth_len *= sizeof(struct sadb_alg); |
1531 | auth_len += sizeof(struct sadb_supported); | 1531 | auth_len += sizeof(struct sadb_supported); |
1532 | } | 1532 | } |
1533 | 1533 | ||
1534 | enc_len = xfrm_count_enc_supported(); | 1534 | enc_len = xfrm_count_enc_supported(); |
1535 | if (enc_len) { | 1535 | if (enc_len) { |
1536 | enc_len *= sizeof(struct sadb_alg); | 1536 | enc_len *= sizeof(struct sadb_alg); |
1537 | enc_len += sizeof(struct sadb_supported); | 1537 | enc_len += sizeof(struct sadb_supported); |
1538 | } | 1538 | } |
1539 | 1539 | ||
1540 | len = enc_len + auth_len + sizeof(struct sadb_msg); | 1540 | len = enc_len + auth_len + sizeof(struct sadb_msg); |
1541 | 1541 | ||
1542 | skb = alloc_skb(len + 16, allocation); | 1542 | skb = alloc_skb(len + 16, allocation); |
@@ -1605,7 +1605,7 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
1605 | } | 1605 | } |
1606 | 1606 | ||
1607 | xfrm_probe_algs(); | 1607 | xfrm_probe_algs(); |
1608 | 1608 | ||
1609 | supp_skb = compose_sadb_supported(hdr, GFP_KERNEL); | 1609 | supp_skb = compose_sadb_supported(hdr, GFP_KERNEL); |
1610 | if (!supp_skb) { | 1610 | if (!supp_skb) { |
1611 | if (hdr->sadb_msg_satype != SADB_SATYPE_UNSPEC) | 1611 | if (hdr->sadb_msg_satype != SADB_SATYPE_UNSPEC) |
@@ -1856,7 +1856,7 @@ static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp) | |||
1856 | 1856 | ||
1857 | return sizeof(struct sadb_msg) + | 1857 | return sizeof(struct sadb_msg) + |
1858 | (sizeof(struct sadb_lifetime) * 3) + | 1858 | (sizeof(struct sadb_lifetime) * 3) + |
1859 | (sizeof(struct sadb_address) * 2) + | 1859 | (sizeof(struct sadb_address) * 2) + |
1860 | (sockaddr_size * 2) + | 1860 | (sockaddr_size * 2) + |
1861 | sizeof(struct sadb_x_policy) + | 1861 | sizeof(struct sadb_x_policy) + |
1862 | (xp->xfrm_nr * sizeof(struct sadb_x_ipsecrequest)) + | 1862 | (xp->xfrm_nr * sizeof(struct sadb_x_ipsecrequest)) + |
@@ -1904,9 +1904,9 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i | |||
1904 | memset(hdr, 0, size); /* XXX do we need this ? */ | 1904 | memset(hdr, 0, size); /* XXX do we need this ? */ |
1905 | 1905 | ||
1906 | /* src address */ | 1906 | /* src address */ |
1907 | addr = (struct sadb_address*) skb_put(skb, | 1907 | addr = (struct sadb_address*) skb_put(skb, |
1908 | sizeof(struct sadb_address)+sockaddr_size); | 1908 | sizeof(struct sadb_address)+sockaddr_size); |
1909 | addr->sadb_address_len = | 1909 | addr->sadb_address_len = |
1910 | (sizeof(struct sadb_address)+sockaddr_size)/ | 1910 | (sizeof(struct sadb_address)+sockaddr_size)/ |
1911 | sizeof(uint64_t); | 1911 | sizeof(uint64_t); |
1912 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; | 1912 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; |
@@ -1936,14 +1936,14 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i | |||
1936 | BUG(); | 1936 | BUG(); |
1937 | 1937 | ||
1938 | /* dst address */ | 1938 | /* dst address */ |
1939 | addr = (struct sadb_address*) skb_put(skb, | 1939 | addr = (struct sadb_address*) skb_put(skb, |
1940 | sizeof(struct sadb_address)+sockaddr_size); | 1940 | sizeof(struct sadb_address)+sockaddr_size); |
1941 | addr->sadb_address_len = | 1941 | addr->sadb_address_len = |
1942 | (sizeof(struct sadb_address)+sockaddr_size)/ | 1942 | (sizeof(struct sadb_address)+sockaddr_size)/ |
1943 | sizeof(uint64_t); | 1943 | sizeof(uint64_t); |
1944 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; | 1944 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; |
1945 | addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); | 1945 | addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); |
1946 | addr->sadb_address_prefixlen = xp->selector.prefixlen_d; | 1946 | addr->sadb_address_prefixlen = xp->selector.prefixlen_d; |
1947 | addr->sadb_address_reserved = 0; | 1947 | addr->sadb_address_reserved = 0; |
1948 | if (xp->family == AF_INET) { | 1948 | if (xp->family == AF_INET) { |
1949 | sin = (struct sockaddr_in *) (addr + 1); | 1949 | sin = (struct sockaddr_in *) (addr + 1); |
@@ -1967,7 +1967,7 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i | |||
1967 | BUG(); | 1967 | BUG(); |
1968 | 1968 | ||
1969 | /* hard time */ | 1969 | /* hard time */ |
1970 | lifetime = (struct sadb_lifetime *) skb_put(skb, | 1970 | lifetime = (struct sadb_lifetime *) skb_put(skb, |
1971 | sizeof(struct sadb_lifetime)); | 1971 | sizeof(struct sadb_lifetime)); |
1972 | lifetime->sadb_lifetime_len = | 1972 | lifetime->sadb_lifetime_len = |
1973 | sizeof(struct sadb_lifetime)/sizeof(uint64_t); | 1973 | sizeof(struct sadb_lifetime)/sizeof(uint64_t); |
@@ -1977,7 +1977,7 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i | |||
1977 | lifetime->sadb_lifetime_addtime = xp->lft.hard_add_expires_seconds; | 1977 | lifetime->sadb_lifetime_addtime = xp->lft.hard_add_expires_seconds; |
1978 | lifetime->sadb_lifetime_usetime = xp->lft.hard_use_expires_seconds; | 1978 | lifetime->sadb_lifetime_usetime = xp->lft.hard_use_expires_seconds; |
1979 | /* soft time */ | 1979 | /* soft time */ |
1980 | lifetime = (struct sadb_lifetime *) skb_put(skb, | 1980 | lifetime = (struct sadb_lifetime *) skb_put(skb, |
1981 | sizeof(struct sadb_lifetime)); | 1981 | sizeof(struct sadb_lifetime)); |
1982 | lifetime->sadb_lifetime_len = | 1982 | lifetime->sadb_lifetime_len = |
1983 | sizeof(struct sadb_lifetime)/sizeof(uint64_t); | 1983 | sizeof(struct sadb_lifetime)/sizeof(uint64_t); |
@@ -1987,7 +1987,7 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i | |||
1987 | lifetime->sadb_lifetime_addtime = xp->lft.soft_add_expires_seconds; | 1987 | lifetime->sadb_lifetime_addtime = xp->lft.soft_add_expires_seconds; |
1988 | lifetime->sadb_lifetime_usetime = xp->lft.soft_use_expires_seconds; | 1988 | lifetime->sadb_lifetime_usetime = xp->lft.soft_use_expires_seconds; |
1989 | /* current time */ | 1989 | /* current time */ |
1990 | lifetime = (struct sadb_lifetime *) skb_put(skb, | 1990 | lifetime = (struct sadb_lifetime *) skb_put(skb, |
1991 | sizeof(struct sadb_lifetime)); | 1991 | sizeof(struct sadb_lifetime)); |
1992 | lifetime->sadb_lifetime_len = | 1992 | lifetime->sadb_lifetime_len = |
1993 | sizeof(struct sadb_lifetime)/sizeof(uint64_t); | 1993 | sizeof(struct sadb_lifetime)/sizeof(uint64_t); |
@@ -2019,8 +2019,8 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i | |||
2019 | req_size = sizeof(struct sadb_x_ipsecrequest); | 2019 | req_size = sizeof(struct sadb_x_ipsecrequest); |
2020 | if (t->mode == XFRM_MODE_TUNNEL) | 2020 | if (t->mode == XFRM_MODE_TUNNEL) |
2021 | req_size += ((t->encap_family == AF_INET ? | 2021 | req_size += ((t->encap_family == AF_INET ? |
2022 | sizeof(struct sockaddr_in) : | 2022 | sizeof(struct sockaddr_in) : |
2023 | sizeof(struct sockaddr_in6)) * 2); | 2023 | sizeof(struct sockaddr_in6)) * 2); |
2024 | else | 2024 | else |
2025 | size -= 2*socklen; | 2025 | size -= 2*socklen; |
2026 | rq = (void*)skb_put(skb, req_size); | 2026 | rq = (void*)skb_put(skb, req_size); |
@@ -2150,7 +2150,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2150 | XFRM_POLICY_BLOCK : XFRM_POLICY_ALLOW); | 2150 | XFRM_POLICY_BLOCK : XFRM_POLICY_ALLOW); |
2151 | xp->priority = pol->sadb_x_policy_priority; | 2151 | xp->priority = pol->sadb_x_policy_priority; |
2152 | 2152 | ||
2153 | sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1], | 2153 | sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1], |
2154 | xp->family = pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.saddr); | 2154 | xp->family = pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.saddr); |
2155 | if (!xp->family) { | 2155 | if (!xp->family) { |
2156 | err = -EINVAL; | 2156 | err = -EINVAL; |
@@ -2163,7 +2163,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2163 | if (xp->selector.sport) | 2163 | if (xp->selector.sport) |
2164 | xp->selector.sport_mask = htons(0xffff); | 2164 | xp->selector.sport_mask = htons(0xffff); |
2165 | 2165 | ||
2166 | sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1], | 2166 | sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1], |
2167 | pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.daddr); | 2167 | pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.daddr); |
2168 | xp->selector.prefixlen_d = sa->sadb_address_prefixlen; | 2168 | xp->selector.prefixlen_d = sa->sadb_address_prefixlen; |
2169 | 2169 | ||
@@ -2224,7 +2224,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2224 | 2224 | ||
2225 | if (hdr->sadb_msg_type == SADB_X_SPDUPDATE) | 2225 | if (hdr->sadb_msg_type == SADB_X_SPDUPDATE) |
2226 | c.event = XFRM_MSG_UPDPOLICY; | 2226 | c.event = XFRM_MSG_UPDPOLICY; |
2227 | else | 2227 | else |
2228 | c.event = XFRM_MSG_NEWPOLICY; | 2228 | c.event = XFRM_MSG_NEWPOLICY; |
2229 | 2229 | ||
2230 | c.seq = hdr->sadb_msg_seq; | 2230 | c.seq = hdr->sadb_msg_seq; |
@@ -2261,7 +2261,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2261 | 2261 | ||
2262 | memset(&sel, 0, sizeof(sel)); | 2262 | memset(&sel, 0, sizeof(sel)); |
2263 | 2263 | ||
2264 | sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1], | 2264 | sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1], |
2265 | sel.family = pfkey_sadb_addr2xfrm_addr(sa, &sel.saddr); | 2265 | sel.family = pfkey_sadb_addr2xfrm_addr(sa, &sel.saddr); |
2266 | sel.prefixlen_s = sa->sadb_address_prefixlen; | 2266 | sel.prefixlen_s = sa->sadb_address_prefixlen; |
2267 | sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); | 2267 | sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); |
@@ -2269,7 +2269,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2269 | if (sel.sport) | 2269 | if (sel.sport) |
2270 | sel.sport_mask = htons(0xffff); | 2270 | sel.sport_mask = htons(0xffff); |
2271 | 2271 | ||
2272 | sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1], | 2272 | sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1], |
2273 | pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr); | 2273 | pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr); |
2274 | sel.prefixlen_d = sa->sadb_address_prefixlen; | 2274 | sel.prefixlen_d = sa->sadb_address_prefixlen; |
2275 | sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); | 2275 | sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); |
@@ -2297,16 +2297,17 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2297 | &sel, tmp.security, 1); | 2297 | &sel, tmp.security, 1); |
2298 | security_xfrm_policy_free(&tmp); | 2298 | security_xfrm_policy_free(&tmp); |
2299 | 2299 | ||
2300 | xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, | ||
2301 | AUDIT_MAC_IPSEC_DELSPD, (xp) ? 1 : 0, xp, NULL); | ||
2302 | |||
2303 | if (xp == NULL) | 2300 | if (xp == NULL) |
2304 | return -ENOENT; | 2301 | return -ENOENT; |
2305 | 2302 | ||
2306 | err = 0; | 2303 | err = security_xfrm_policy_delete(xp); |
2304 | |||
2305 | xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, | ||
2306 | AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); | ||
2307 | 2307 | ||
2308 | if ((err = security_xfrm_policy_delete(xp))) | 2308 | if (err) |
2309 | goto out; | 2309 | goto out; |
2310 | |||
2310 | c.seq = hdr->sadb_msg_seq; | 2311 | c.seq = hdr->sadb_msg_seq; |
2311 | c.pid = hdr->sadb_msg_pid; | 2312 | c.pid = hdr->sadb_msg_pid; |
2312 | c.event = XFRM_MSG_DELPOLICY; | 2313 | c.event = XFRM_MSG_DELPOLICY; |
@@ -2345,6 +2346,196 @@ out: | |||
2345 | return err; | 2346 | return err; |
2346 | } | 2347 | } |
2347 | 2348 | ||
2349 | #ifdef CONFIG_NET_KEY_MIGRATE | ||
2350 | static int pfkey_sockaddr_pair_size(sa_family_t family) | ||
2351 | { | ||
2352 | switch (family) { | ||
2353 | case AF_INET: | ||
2354 | return PFKEY_ALIGN8(sizeof(struct sockaddr_in) * 2); | ||
2355 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
2356 | case AF_INET6: | ||
2357 | return PFKEY_ALIGN8(sizeof(struct sockaddr_in6) * 2); | ||
2358 | #endif | ||
2359 | default: | ||
2360 | return 0; | ||
2361 | } | ||
2362 | /* NOTREACHED */ | ||
2363 | } | ||
2364 | |||
2365 | static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq, | ||
2366 | xfrm_address_t *saddr, xfrm_address_t *daddr, | ||
2367 | u16 *family) | ||
2368 | { | ||
2369 | struct sockaddr *sa = (struct sockaddr *)(rq + 1); | ||
2370 | if (rq->sadb_x_ipsecrequest_len < | ||
2371 | pfkey_sockaddr_pair_size(sa->sa_family)) | ||
2372 | return -EINVAL; | ||
2373 | |||
2374 | switch (sa->sa_family) { | ||
2375 | case AF_INET: | ||
2376 | { | ||
2377 | struct sockaddr_in *sin; | ||
2378 | sin = (struct sockaddr_in *)sa; | ||
2379 | if ((sin+1)->sin_family != AF_INET) | ||
2380 | return -EINVAL; | ||
2381 | memcpy(&saddr->a4, &sin->sin_addr, sizeof(saddr->a4)); | ||
2382 | sin++; | ||
2383 | memcpy(&daddr->a4, &sin->sin_addr, sizeof(daddr->a4)); | ||
2384 | *family = AF_INET; | ||
2385 | break; | ||
2386 | } | ||
2387 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
2388 | case AF_INET6: | ||
2389 | { | ||
2390 | struct sockaddr_in6 *sin6; | ||
2391 | sin6 = (struct sockaddr_in6 *)sa; | ||
2392 | if ((sin6+1)->sin6_family != AF_INET6) | ||
2393 | return -EINVAL; | ||
2394 | memcpy(&saddr->a6, &sin6->sin6_addr, | ||
2395 | sizeof(saddr->a6)); | ||
2396 | sin6++; | ||
2397 | memcpy(&daddr->a6, &sin6->sin6_addr, | ||
2398 | sizeof(daddr->a6)); | ||
2399 | *family = AF_INET6; | ||
2400 | break; | ||
2401 | } | ||
2402 | #endif | ||
2403 | default: | ||
2404 | return -EINVAL; | ||
2405 | } | ||
2406 | |||
2407 | return 0; | ||
2408 | } | ||
2409 | |||
2410 | static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len, | ||
2411 | struct xfrm_migrate *m) | ||
2412 | { | ||
2413 | int err; | ||
2414 | struct sadb_x_ipsecrequest *rq2; | ||
2415 | |||
2416 | if (len <= sizeof(struct sadb_x_ipsecrequest) || | ||
2417 | len < rq1->sadb_x_ipsecrequest_len) | ||
2418 | return -EINVAL; | ||
2419 | |||
2420 | /* old endoints */ | ||
2421 | err = parse_sockaddr_pair(rq1, &m->old_saddr, &m->old_daddr, | ||
2422 | &m->old_family); | ||
2423 | if (err) | ||
2424 | return err; | ||
2425 | |||
2426 | rq2 = (struct sadb_x_ipsecrequest *)((u8 *)rq1 + rq1->sadb_x_ipsecrequest_len); | ||
2427 | len -= rq1->sadb_x_ipsecrequest_len; | ||
2428 | |||
2429 | if (len <= sizeof(struct sadb_x_ipsecrequest) || | ||
2430 | len < rq2->sadb_x_ipsecrequest_len) | ||
2431 | return -EINVAL; | ||
2432 | |||
2433 | /* new endpoints */ | ||
2434 | err = parse_sockaddr_pair(rq2, &m->new_saddr, &m->new_daddr, | ||
2435 | &m->new_family); | ||
2436 | if (err) | ||
2437 | return err; | ||
2438 | |||
2439 | if (rq1->sadb_x_ipsecrequest_proto != rq2->sadb_x_ipsecrequest_proto || | ||
2440 | rq1->sadb_x_ipsecrequest_mode != rq2->sadb_x_ipsecrequest_mode || | ||
2441 | rq1->sadb_x_ipsecrequest_reqid != rq2->sadb_x_ipsecrequest_reqid) | ||
2442 | return -EINVAL; | ||
2443 | |||
2444 | m->proto = rq1->sadb_x_ipsecrequest_proto; | ||
2445 | m->mode = rq1->sadb_x_ipsecrequest_mode - 1; | ||
2446 | m->reqid = rq1->sadb_x_ipsecrequest_reqid; | ||
2447 | |||
2448 | return ((int)(rq1->sadb_x_ipsecrequest_len + | ||
2449 | rq2->sadb_x_ipsecrequest_len)); | ||
2450 | } | ||
2451 | |||
2452 | static int pfkey_migrate(struct sock *sk, struct sk_buff *skb, | ||
2453 | struct sadb_msg *hdr, void **ext_hdrs) | ||
2454 | { | ||
2455 | int i, len, ret, err = -EINVAL; | ||
2456 | u8 dir; | ||
2457 | struct sadb_address *sa; | ||
2458 | struct sadb_x_policy *pol; | ||
2459 | struct sadb_x_ipsecrequest *rq; | ||
2460 | struct xfrm_selector sel; | ||
2461 | struct xfrm_migrate m[XFRM_MAX_DEPTH]; | ||
2462 | |||
2463 | if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC - 1], | ||
2464 | ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) || | ||
2465 | !ext_hdrs[SADB_X_EXT_POLICY - 1]) { | ||
2466 | err = -EINVAL; | ||
2467 | goto out; | ||
2468 | } | ||
2469 | |||
2470 | pol = ext_hdrs[SADB_X_EXT_POLICY - 1]; | ||
2471 | if (!pol) { | ||
2472 | err = -EINVAL; | ||
2473 | goto out; | ||
2474 | } | ||
2475 | |||
2476 | if (pol->sadb_x_policy_dir >= IPSEC_DIR_MAX) { | ||
2477 | err = -EINVAL; | ||
2478 | goto out; | ||
2479 | } | ||
2480 | |||
2481 | dir = pol->sadb_x_policy_dir - 1; | ||
2482 | memset(&sel, 0, sizeof(sel)); | ||
2483 | |||
2484 | /* set source address info of selector */ | ||
2485 | sa = ext_hdrs[SADB_EXT_ADDRESS_SRC - 1]; | ||
2486 | sel.family = pfkey_sadb_addr2xfrm_addr(sa, &sel.saddr); | ||
2487 | sel.prefixlen_s = sa->sadb_address_prefixlen; | ||
2488 | sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); | ||
2489 | sel.sport = ((struct sockaddr_in *)(sa + 1))->sin_port; | ||
2490 | if (sel.sport) | ||
2491 | sel.sport_mask = ~0; | ||
2492 | |||
2493 | /* set destination address info of selector */ | ||
2494 | sa = ext_hdrs[SADB_EXT_ADDRESS_DST - 1], | ||
2495 | pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr); | ||
2496 | sel.prefixlen_d = sa->sadb_address_prefixlen; | ||
2497 | sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); | ||
2498 | sel.dport = ((struct sockaddr_in *)(sa + 1))->sin_port; | ||
2499 | if (sel.dport) | ||
2500 | sel.dport_mask = ~0; | ||
2501 | |||
2502 | rq = (struct sadb_x_ipsecrequest *)(pol + 1); | ||
2503 | |||
2504 | /* extract ipsecrequests */ | ||
2505 | i = 0; | ||
2506 | len = pol->sadb_x_policy_len * 8 - sizeof(struct sadb_x_policy); | ||
2507 | |||
2508 | while (len > 0 && i < XFRM_MAX_DEPTH) { | ||
2509 | ret = ipsecrequests_to_migrate(rq, len, &m[i]); | ||
2510 | if (ret < 0) { | ||
2511 | err = ret; | ||
2512 | goto out; | ||
2513 | } else { | ||
2514 | rq = (struct sadb_x_ipsecrequest *)((u8 *)rq + ret); | ||
2515 | len -= ret; | ||
2516 | i++; | ||
2517 | } | ||
2518 | } | ||
2519 | |||
2520 | if (!i || len > 0) { | ||
2521 | err = -EINVAL; | ||
2522 | goto out; | ||
2523 | } | ||
2524 | |||
2525 | return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i); | ||
2526 | |||
2527 | out: | ||
2528 | return err; | ||
2529 | } | ||
2530 | #else | ||
2531 | static int pfkey_migrate(struct sock *sk, struct sk_buff *skb, | ||
2532 | struct sadb_msg *hdr, void **ext_hdrs) | ||
2533 | { | ||
2534 | return -ENOPROTOOPT; | ||
2535 | } | ||
2536 | #endif | ||
2537 | |||
2538 | |||
2348 | static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 2539 | static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
2349 | { | 2540 | { |
2350 | unsigned int dir; | 2541 | unsigned int dir; |
@@ -2473,6 +2664,7 @@ static pfkey_handler pfkey_funcs[SADB_MAX + 1] = { | |||
2473 | [SADB_X_SPDFLUSH] = pfkey_spdflush, | 2664 | [SADB_X_SPDFLUSH] = pfkey_spdflush, |
2474 | [SADB_X_SPDSETIDX] = pfkey_spdadd, | 2665 | [SADB_X_SPDSETIDX] = pfkey_spdadd, |
2475 | [SADB_X_SPDDELETE2] = pfkey_spdget, | 2666 | [SADB_X_SPDDELETE2] = pfkey_spdget, |
2667 | [SADB_X_MIGRATE] = pfkey_migrate, | ||
2476 | }; | 2668 | }; |
2477 | 2669 | ||
2478 | static int pfkey_process(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr) | 2670 | static int pfkey_process(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr) |
@@ -2552,15 +2744,15 @@ static int count_esp_combs(struct xfrm_tmpl *t) | |||
2552 | struct xfrm_algo_desc *ealg = xfrm_ealg_get_byidx(i); | 2744 | struct xfrm_algo_desc *ealg = xfrm_ealg_get_byidx(i); |
2553 | if (!ealg) | 2745 | if (!ealg) |
2554 | break; | 2746 | break; |
2555 | 2747 | ||
2556 | if (!(ealg_tmpl_set(t, ealg) && ealg->available)) | 2748 | if (!(ealg_tmpl_set(t, ealg) && ealg->available)) |
2557 | continue; | 2749 | continue; |
2558 | 2750 | ||
2559 | for (k = 1; ; k++) { | 2751 | for (k = 1; ; k++) { |
2560 | struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(k); | 2752 | struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(k); |
2561 | if (!aalg) | 2753 | if (!aalg) |
2562 | break; | 2754 | break; |
2563 | 2755 | ||
2564 | if (aalg_tmpl_set(t, aalg) && aalg->available) | 2756 | if (aalg_tmpl_set(t, aalg) && aalg->available) |
2565 | sz += sizeof(struct sadb_comb); | 2757 | sz += sizeof(struct sadb_comb); |
2566 | } | 2758 | } |
@@ -2615,10 +2807,10 @@ static void dump_esp_combs(struct sk_buff *skb, struct xfrm_tmpl *t) | |||
2615 | struct xfrm_algo_desc *ealg = xfrm_ealg_get_byidx(i); | 2807 | struct xfrm_algo_desc *ealg = xfrm_ealg_get_byidx(i); |
2616 | if (!ealg) | 2808 | if (!ealg) |
2617 | break; | 2809 | break; |
2618 | 2810 | ||
2619 | if (!(ealg_tmpl_set(t, ealg) && ealg->available)) | 2811 | if (!(ealg_tmpl_set(t, ealg) && ealg->available)) |
2620 | continue; | 2812 | continue; |
2621 | 2813 | ||
2622 | for (k = 1; ; k++) { | 2814 | for (k = 1; ; k++) { |
2623 | struct sadb_comb *c; | 2815 | struct sadb_comb *c; |
2624 | struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(k); | 2816 | struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(k); |
@@ -2750,7 +2942,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
2750 | struct sadb_x_sec_ctx *sec_ctx; | 2942 | struct sadb_x_sec_ctx *sec_ctx; |
2751 | struct xfrm_sec_ctx *xfrm_ctx; | 2943 | struct xfrm_sec_ctx *xfrm_ctx; |
2752 | int ctx_size = 0; | 2944 | int ctx_size = 0; |
2753 | 2945 | ||
2754 | sockaddr_size = pfkey_sockaddr_size(x->props.family); | 2946 | sockaddr_size = pfkey_sockaddr_size(x->props.family); |
2755 | if (!sockaddr_size) | 2947 | if (!sockaddr_size) |
2756 | return -EINVAL; | 2948 | return -EINVAL; |
@@ -2759,7 +2951,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
2759 | (sizeof(struct sadb_address) * 2) + | 2951 | (sizeof(struct sadb_address) * 2) + |
2760 | (sockaddr_size * 2) + | 2952 | (sockaddr_size * 2) + |
2761 | sizeof(struct sadb_x_policy); | 2953 | sizeof(struct sadb_x_policy); |
2762 | 2954 | ||
2763 | if (x->id.proto == IPPROTO_AH) | 2955 | if (x->id.proto == IPPROTO_AH) |
2764 | size += count_ah_combs(t); | 2956 | size += count_ah_combs(t); |
2765 | else if (x->id.proto == IPPROTO_ESP) | 2957 | else if (x->id.proto == IPPROTO_ESP) |
@@ -2773,7 +2965,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
2773 | skb = alloc_skb(size + 16, GFP_ATOMIC); | 2965 | skb = alloc_skb(size + 16, GFP_ATOMIC); |
2774 | if (skb == NULL) | 2966 | if (skb == NULL) |
2775 | return -ENOMEM; | 2967 | return -ENOMEM; |
2776 | 2968 | ||
2777 | hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg)); | 2969 | hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg)); |
2778 | hdr->sadb_msg_version = PF_KEY_V2; | 2970 | hdr->sadb_msg_version = PF_KEY_V2; |
2779 | hdr->sadb_msg_type = SADB_ACQUIRE; | 2971 | hdr->sadb_msg_type = SADB_ACQUIRE; |
@@ -2785,9 +2977,9 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
2785 | hdr->sadb_msg_pid = 0; | 2977 | hdr->sadb_msg_pid = 0; |
2786 | 2978 | ||
2787 | /* src address */ | 2979 | /* src address */ |
2788 | addr = (struct sadb_address*) skb_put(skb, | 2980 | addr = (struct sadb_address*) skb_put(skb, |
2789 | sizeof(struct sadb_address)+sockaddr_size); | 2981 | sizeof(struct sadb_address)+sockaddr_size); |
2790 | addr->sadb_address_len = | 2982 | addr->sadb_address_len = |
2791 | (sizeof(struct sadb_address)+sockaddr_size)/ | 2983 | (sizeof(struct sadb_address)+sockaddr_size)/ |
2792 | sizeof(uint64_t); | 2984 | sizeof(uint64_t); |
2793 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; | 2985 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; |
@@ -2817,9 +3009,9 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
2817 | #endif | 3009 | #endif |
2818 | else | 3010 | else |
2819 | BUG(); | 3011 | BUG(); |
2820 | 3012 | ||
2821 | /* dst address */ | 3013 | /* dst address */ |
2822 | addr = (struct sadb_address*) skb_put(skb, | 3014 | addr = (struct sadb_address*) skb_put(skb, |
2823 | sizeof(struct sadb_address)+sockaddr_size); | 3015 | sizeof(struct sadb_address)+sockaddr_size); |
2824 | addr->sadb_address_len = | 3016 | addr->sadb_address_len = |
2825 | (sizeof(struct sadb_address)+sockaddr_size)/ | 3017 | (sizeof(struct sadb_address)+sockaddr_size)/ |
@@ -2828,7 +3020,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
2828 | addr->sadb_address_proto = 0; | 3020 | addr->sadb_address_proto = 0; |
2829 | addr->sadb_address_reserved = 0; | 3021 | addr->sadb_address_reserved = 0; |
2830 | if (x->props.family == AF_INET) { | 3022 | if (x->props.family == AF_INET) { |
2831 | addr->sadb_address_prefixlen = 32; | 3023 | addr->sadb_address_prefixlen = 32; |
2832 | 3024 | ||
2833 | sin = (struct sockaddr_in *) (addr + 1); | 3025 | sin = (struct sockaddr_in *) (addr + 1); |
2834 | sin->sin_family = AF_INET; | 3026 | sin->sin_family = AF_INET; |
@@ -2838,7 +3030,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
2838 | } | 3030 | } |
2839 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 3031 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
2840 | else if (x->props.family == AF_INET6) { | 3032 | else if (x->props.family == AF_INET6) { |
2841 | addr->sadb_address_prefixlen = 128; | 3033 | addr->sadb_address_prefixlen = 128; |
2842 | 3034 | ||
2843 | sin6 = (struct sockaddr_in6 *) (addr + 1); | 3035 | sin6 = (struct sockaddr_in6 *) (addr + 1); |
2844 | sin6->sin6_family = AF_INET6; | 3036 | sin6->sin6_family = AF_INET6; |
@@ -2883,7 +3075,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct | |||
2883 | } | 3075 | } |
2884 | 3076 | ||
2885 | static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, | 3077 | static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, |
2886 | u8 *data, int len, int *dir) | 3078 | u8 *data, int len, int *dir) |
2887 | { | 3079 | { |
2888 | struct xfrm_policy *xp; | 3080 | struct xfrm_policy *xp; |
2889 | struct sadb_x_policy *pol = (struct sadb_x_policy*)data; | 3081 | struct sadb_x_policy *pol = (struct sadb_x_policy*)data; |
@@ -3002,17 +3194,17 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, | |||
3002 | * HDR | SA | ADDRESS_SRC (old addr) | NAT_T_SPORT (old port) | | 3194 | * HDR | SA | ADDRESS_SRC (old addr) | NAT_T_SPORT (old port) | |
3003 | * ADDRESS_DST (new addr) | NAT_T_DPORT (new port) | 3195 | * ADDRESS_DST (new addr) | NAT_T_DPORT (new port) |
3004 | */ | 3196 | */ |
3005 | 3197 | ||
3006 | size = sizeof(struct sadb_msg) + | 3198 | size = sizeof(struct sadb_msg) + |
3007 | sizeof(struct sadb_sa) + | 3199 | sizeof(struct sadb_sa) + |
3008 | (sizeof(struct sadb_address) * 2) + | 3200 | (sizeof(struct sadb_address) * 2) + |
3009 | (sockaddr_size * 2) + | 3201 | (sockaddr_size * 2) + |
3010 | (sizeof(struct sadb_x_nat_t_port) * 2); | 3202 | (sizeof(struct sadb_x_nat_t_port) * 2); |
3011 | 3203 | ||
3012 | skb = alloc_skb(size + 16, GFP_ATOMIC); | 3204 | skb = alloc_skb(size + 16, GFP_ATOMIC); |
3013 | if (skb == NULL) | 3205 | if (skb == NULL) |
3014 | return -ENOMEM; | 3206 | return -ENOMEM; |
3015 | 3207 | ||
3016 | hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg)); | 3208 | hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg)); |
3017 | hdr->sadb_msg_version = PF_KEY_V2; | 3209 | hdr->sadb_msg_version = PF_KEY_V2; |
3018 | hdr->sadb_msg_type = SADB_X_NAT_T_NEW_MAPPING; | 3210 | hdr->sadb_msg_type = SADB_X_NAT_T_NEW_MAPPING; |
@@ -3037,7 +3229,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, | |||
3037 | /* ADDRESS_SRC (old addr) */ | 3229 | /* ADDRESS_SRC (old addr) */ |
3038 | addr = (struct sadb_address*) | 3230 | addr = (struct sadb_address*) |
3039 | skb_put(skb, sizeof(struct sadb_address)+sockaddr_size); | 3231 | skb_put(skb, sizeof(struct sadb_address)+sockaddr_size); |
3040 | addr->sadb_address_len = | 3232 | addr->sadb_address_len = |
3041 | (sizeof(struct sadb_address)+sockaddr_size)/ | 3233 | (sizeof(struct sadb_address)+sockaddr_size)/ |
3042 | sizeof(uint64_t); | 3234 | sizeof(uint64_t); |
3043 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; | 3235 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; |
@@ -3078,7 +3270,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, | |||
3078 | /* ADDRESS_DST (new addr) */ | 3270 | /* ADDRESS_DST (new addr) */ |
3079 | addr = (struct sadb_address*) | 3271 | addr = (struct sadb_address*) |
3080 | skb_put(skb, sizeof(struct sadb_address)+sockaddr_size); | 3272 | skb_put(skb, sizeof(struct sadb_address)+sockaddr_size); |
3081 | addr->sadb_address_len = | 3273 | addr->sadb_address_len = |
3082 | (sizeof(struct sadb_address)+sockaddr_size)/ | 3274 | (sizeof(struct sadb_address)+sockaddr_size)/ |
3083 | sizeof(uint64_t); | 3275 | sizeof(uint64_t); |
3084 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; | 3276 | addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; |
@@ -3118,6 +3310,236 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, | |||
3118 | return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL); | 3310 | return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL); |
3119 | } | 3311 | } |
3120 | 3312 | ||
3313 | #ifdef CONFIG_NET_KEY_MIGRATE | ||
3314 | static int set_sadb_address(struct sk_buff *skb, int sasize, int type, | ||
3315 | struct xfrm_selector *sel) | ||
3316 | { | ||
3317 | struct sadb_address *addr; | ||
3318 | struct sockaddr_in *sin; | ||
3319 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
3320 | struct sockaddr_in6 *sin6; | ||
3321 | #endif | ||
3322 | addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize); | ||
3323 | addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8; | ||
3324 | addr->sadb_address_exttype = type; | ||
3325 | addr->sadb_address_proto = sel->proto; | ||
3326 | addr->sadb_address_reserved = 0; | ||
3327 | |||
3328 | switch (type) { | ||
3329 | case SADB_EXT_ADDRESS_SRC: | ||
3330 | if (sel->family == AF_INET) { | ||
3331 | addr->sadb_address_prefixlen = sel->prefixlen_s; | ||
3332 | sin = (struct sockaddr_in *)(addr + 1); | ||
3333 | sin->sin_family = AF_INET; | ||
3334 | memcpy(&sin->sin_addr.s_addr, &sel->saddr, | ||
3335 | sizeof(sin->sin_addr.s_addr)); | ||
3336 | sin->sin_port = 0; | ||
3337 | memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); | ||
3338 | } | ||
3339 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
3340 | else if (sel->family == AF_INET6) { | ||
3341 | addr->sadb_address_prefixlen = sel->prefixlen_s; | ||
3342 | sin6 = (struct sockaddr_in6 *)(addr + 1); | ||
3343 | sin6->sin6_family = AF_INET6; | ||
3344 | sin6->sin6_port = 0; | ||
3345 | sin6->sin6_flowinfo = 0; | ||
3346 | sin6->sin6_scope_id = 0; | ||
3347 | memcpy(&sin6->sin6_addr.s6_addr, &sel->saddr, | ||
3348 | sizeof(sin6->sin6_addr.s6_addr)); | ||
3349 | } | ||
3350 | #endif | ||
3351 | break; | ||
3352 | case SADB_EXT_ADDRESS_DST: | ||
3353 | if (sel->family == AF_INET) { | ||
3354 | addr->sadb_address_prefixlen = sel->prefixlen_d; | ||
3355 | sin = (struct sockaddr_in *)(addr + 1); | ||
3356 | sin->sin_family = AF_INET; | ||
3357 | memcpy(&sin->sin_addr.s_addr, &sel->daddr, | ||
3358 | sizeof(sin->sin_addr.s_addr)); | ||
3359 | sin->sin_port = 0; | ||
3360 | memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); | ||
3361 | } | ||
3362 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
3363 | else if (sel->family == AF_INET6) { | ||
3364 | addr->sadb_address_prefixlen = sel->prefixlen_d; | ||
3365 | sin6 = (struct sockaddr_in6 *)(addr + 1); | ||
3366 | sin6->sin6_family = AF_INET6; | ||
3367 | sin6->sin6_port = 0; | ||
3368 | sin6->sin6_flowinfo = 0; | ||
3369 | sin6->sin6_scope_id = 0; | ||
3370 | memcpy(&sin6->sin6_addr.s6_addr, &sel->daddr, | ||
3371 | sizeof(sin6->sin6_addr.s6_addr)); | ||
3372 | } | ||
3373 | #endif | ||
3374 | break; | ||
3375 | default: | ||
3376 | return -EINVAL; | ||
3377 | } | ||
3378 | |||
3379 | return 0; | ||
3380 | } | ||
3381 | |||
3382 | static int set_ipsecrequest(struct sk_buff *skb, | ||
3383 | uint8_t proto, uint8_t mode, int level, | ||
3384 | uint32_t reqid, uint8_t family, | ||
3385 | xfrm_address_t *src, xfrm_address_t *dst) | ||
3386 | { | ||
3387 | struct sadb_x_ipsecrequest *rq; | ||
3388 | struct sockaddr_in *sin; | ||
3389 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
3390 | struct sockaddr_in6 *sin6; | ||
3391 | #endif | ||
3392 | int size_req; | ||
3393 | |||
3394 | size_req = sizeof(struct sadb_x_ipsecrequest) + | ||
3395 | pfkey_sockaddr_pair_size(family); | ||
3396 | |||
3397 | rq = (struct sadb_x_ipsecrequest *)skb_put(skb, size_req); | ||
3398 | memset(rq, 0, size_req); | ||
3399 | rq->sadb_x_ipsecrequest_len = size_req; | ||
3400 | rq->sadb_x_ipsecrequest_proto = proto; | ||
3401 | rq->sadb_x_ipsecrequest_mode = mode; | ||
3402 | rq->sadb_x_ipsecrequest_level = level; | ||
3403 | rq->sadb_x_ipsecrequest_reqid = reqid; | ||
3404 | |||
3405 | switch (family) { | ||
3406 | case AF_INET: | ||
3407 | sin = (struct sockaddr_in *)(rq + 1); | ||
3408 | sin->sin_family = AF_INET; | ||
3409 | memcpy(&sin->sin_addr.s_addr, src, | ||
3410 | sizeof(sin->sin_addr.s_addr)); | ||
3411 | sin++; | ||
3412 | sin->sin_family = AF_INET; | ||
3413 | memcpy(&sin->sin_addr.s_addr, dst, | ||
3414 | sizeof(sin->sin_addr.s_addr)); | ||
3415 | break; | ||
3416 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
3417 | case AF_INET6: | ||
3418 | sin6 = (struct sockaddr_in6 *)(rq + 1); | ||
3419 | sin6->sin6_family = AF_INET6; | ||
3420 | sin6->sin6_port = 0; | ||
3421 | sin6->sin6_flowinfo = 0; | ||
3422 | sin6->sin6_scope_id = 0; | ||
3423 | memcpy(&sin6->sin6_addr.s6_addr, src, | ||
3424 | sizeof(sin6->sin6_addr.s6_addr)); | ||
3425 | sin6++; | ||
3426 | sin6->sin6_family = AF_INET6; | ||
3427 | sin6->sin6_port = 0; | ||
3428 | sin6->sin6_flowinfo = 0; | ||
3429 | sin6->sin6_scope_id = 0; | ||
3430 | memcpy(&sin6->sin6_addr.s6_addr, dst, | ||
3431 | sizeof(sin6->sin6_addr.s6_addr)); | ||
3432 | break; | ||
3433 | #endif | ||
3434 | default: | ||
3435 | return -EINVAL; | ||
3436 | } | ||
3437 | |||
3438 | return 0; | ||
3439 | } | ||
3440 | #endif | ||
3441 | |||
3442 | #ifdef CONFIG_NET_KEY_MIGRATE | ||
3443 | static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, | ||
3444 | struct xfrm_migrate *m, int num_bundles) | ||
3445 | { | ||
3446 | int i; | ||
3447 | int sasize_sel; | ||
3448 | int size = 0; | ||
3449 | int size_pol = 0; | ||
3450 | struct sk_buff *skb; | ||
3451 | struct sadb_msg *hdr; | ||
3452 | struct sadb_x_policy *pol; | ||
3453 | struct xfrm_migrate *mp; | ||
3454 | |||
3455 | if (type != XFRM_POLICY_TYPE_MAIN) | ||
3456 | return 0; | ||
3457 | |||
3458 | if (num_bundles <= 0 || num_bundles > XFRM_MAX_DEPTH) | ||
3459 | return -EINVAL; | ||
3460 | |||
3461 | /* selector */ | ||
3462 | sasize_sel = pfkey_sockaddr_size(sel->family); | ||
3463 | if (!sasize_sel) | ||
3464 | return -EINVAL; | ||
3465 | size += (sizeof(struct sadb_address) + sasize_sel) * 2; | ||
3466 | |||
3467 | /* policy info */ | ||
3468 | size_pol += sizeof(struct sadb_x_policy); | ||
3469 | |||
3470 | /* ipsecrequests */ | ||
3471 | for (i = 0, mp = m; i < num_bundles; i++, mp++) { | ||
3472 | /* old locator pair */ | ||
3473 | size_pol += sizeof(struct sadb_x_ipsecrequest) + | ||
3474 | pfkey_sockaddr_pair_size(mp->old_family); | ||
3475 | /* new locator pair */ | ||
3476 | size_pol += sizeof(struct sadb_x_ipsecrequest) + | ||
3477 | pfkey_sockaddr_pair_size(mp->new_family); | ||
3478 | } | ||
3479 | |||
3480 | size += sizeof(struct sadb_msg) + size_pol; | ||
3481 | |||
3482 | /* alloc buffer */ | ||
3483 | skb = alloc_skb(size, GFP_ATOMIC); | ||
3484 | if (skb == NULL) | ||
3485 | return -ENOMEM; | ||
3486 | |||
3487 | hdr = (struct sadb_msg *)skb_put(skb, sizeof(struct sadb_msg)); | ||
3488 | hdr->sadb_msg_version = PF_KEY_V2; | ||
3489 | hdr->sadb_msg_type = SADB_X_MIGRATE; | ||
3490 | hdr->sadb_msg_satype = pfkey_proto2satype(m->proto); | ||
3491 | hdr->sadb_msg_len = size / 8; | ||
3492 | hdr->sadb_msg_errno = 0; | ||
3493 | hdr->sadb_msg_reserved = 0; | ||
3494 | hdr->sadb_msg_seq = 0; | ||
3495 | hdr->sadb_msg_pid = 0; | ||
3496 | |||
3497 | /* selector src */ | ||
3498 | set_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_SRC, sel); | ||
3499 | |||
3500 | /* selector dst */ | ||
3501 | set_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_DST, sel); | ||
3502 | |||
3503 | /* policy information */ | ||
3504 | pol = (struct sadb_x_policy *)skb_put(skb, sizeof(struct sadb_x_policy)); | ||
3505 | pol->sadb_x_policy_len = size_pol / 8; | ||
3506 | pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; | ||
3507 | pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC; | ||
3508 | pol->sadb_x_policy_dir = dir + 1; | ||
3509 | pol->sadb_x_policy_id = 0; | ||
3510 | pol->sadb_x_policy_priority = 0; | ||
3511 | |||
3512 | for (i = 0, mp = m; i < num_bundles; i++, mp++) { | ||
3513 | /* old ipsecrequest */ | ||
3514 | if (set_ipsecrequest(skb, mp->proto, mp->mode + 1, | ||
3515 | (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), | ||
3516 | mp->reqid, mp->old_family, | ||
3517 | &mp->old_saddr, &mp->old_daddr) < 0) { | ||
3518 | return -EINVAL; | ||
3519 | } | ||
3520 | |||
3521 | /* new ipsecrequest */ | ||
3522 | if (set_ipsecrequest(skb, mp->proto, mp->mode + 1, | ||
3523 | (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), | ||
3524 | mp->reqid, mp->new_family, | ||
3525 | &mp->new_saddr, &mp->new_daddr) < 0) { | ||
3526 | return -EINVAL; | ||
3527 | } | ||
3528 | } | ||
3529 | |||
3530 | /* broadcast migrate message to sockets */ | ||
3531 | pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL); | ||
3532 | |||
3533 | return 0; | ||
3534 | } | ||
3535 | #else | ||
3536 | static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, | ||
3537 | struct xfrm_migrate *m, int num_bundles) | ||
3538 | { | ||
3539 | return -ENOPROTOOPT; | ||
3540 | } | ||
3541 | #endif | ||
3542 | |||
3121 | static int pfkey_sendmsg(struct kiocb *kiocb, | 3543 | static int pfkey_sendmsg(struct kiocb *kiocb, |
3122 | struct socket *sock, struct msghdr *msg, size_t len) | 3544 | struct socket *sock, struct msghdr *msg, size_t len) |
3123 | { | 3545 | { |
@@ -3253,7 +3675,7 @@ static int pfkey_read_proc(char *buffer, char **start, off_t offset, | |||
3253 | ); | 3675 | ); |
3254 | 3676 | ||
3255 | buffer[len++] = '\n'; | 3677 | buffer[len++] = '\n'; |
3256 | 3678 | ||
3257 | pos = begin + len; | 3679 | pos = begin + len; |
3258 | if (pos < offset) { | 3680 | if (pos < offset) { |
3259 | len = 0; | 3681 | len = 0; |
@@ -3287,6 +3709,7 @@ static struct xfrm_mgr pfkeyv2_mgr = | |||
3287 | .compile_policy = pfkey_compile_policy, | 3709 | .compile_policy = pfkey_compile_policy, |
3288 | .new_mapping = pfkey_send_new_mapping, | 3710 | .new_mapping = pfkey_send_new_mapping, |
3289 | .notify_policy = pfkey_send_policy_notify, | 3711 | .notify_policy = pfkey_send_policy_notify, |
3712 | .migrate = pfkey_send_migrate, | ||
3290 | }; | 3713 | }; |
3291 | 3714 | ||
3292 | static void __exit ipsec_pfkey_exit(void) | 3715 | static void __exit ipsec_pfkey_exit(void) |