aboutsummaryrefslogtreecommitdiffstats
path: root/net/key/af_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/key/af_key.c')
-rw-r--r--net/key/af_key.c589
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
982static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, 982static 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
2350static 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
2365static 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
2410static 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
2452static 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
2531static 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
2348static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 2539static 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
2478static int pfkey_process(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr) 2670static 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
2885static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, 3077static 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
3314static 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
3382static 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
3443static 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
3536static 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
3121static int pfkey_sendmsg(struct kiocb *kiocb, 3543static 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
3292static void __exit ipsec_pfkey_exit(void) 3715static void __exit ipsec_pfkey_exit(void)