aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-06-12 01:33:59 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-12 01:33:59 -0400
commite6e30add6bd8115af108de2a13ec82d997a55777 (patch)
tree558b4d1c3ac369805aa9c57abca710bdf52aff75 /net
parentd4c3c0753594adaafbcb77a086f013f1d847b3f0 (diff)
parent9501f9722922f2e80e1f9dc6682311d65c2b5690 (diff)
Merge branch 'net-next-2.6-misc-20080612a' of git://git.linux-ipv6.org/gitroot/yoshfuji/linux-2.6-next
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp.c70
-rw-r--r--net/ipv4/tcp_input.c40
-rw-r--r--net/ipv4/tcp_ipv4.c164
-rw-r--r--net/ipv4/tcp_output.c3
-rw-r--r--net/ipv6/addrconf.c22
-rw-r--r--net/ipv6/addrlabel.c106
-rw-r--r--net/ipv6/ip6mr.c2
-rw-r--r--net/ipv6/mcast.c1
-rw-r--r--net/ipv6/tcp_ipv6.c136
-rw-r--r--net/key/af_key.c622
10 files changed, 428 insertions, 738 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index ad66b09e0bcd..6d30ca559c64 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2457,6 +2457,76 @@ static unsigned long tcp_md5sig_users;
2457static struct tcp_md5sig_pool **tcp_md5sig_pool; 2457static struct tcp_md5sig_pool **tcp_md5sig_pool;
2458static DEFINE_SPINLOCK(tcp_md5sig_pool_lock); 2458static DEFINE_SPINLOCK(tcp_md5sig_pool_lock);
2459 2459
2460int tcp_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
2461 int bplen,
2462 struct tcphdr *th, unsigned int tcplen,
2463 struct tcp_md5sig_pool *hp)
2464{
2465 struct scatterlist sg[4];
2466 __u16 data_len;
2467 int block = 0;
2468 __sum16 cksum;
2469 struct hash_desc *desc = &hp->md5_desc;
2470 int err;
2471 unsigned int nbytes = 0;
2472
2473 sg_init_table(sg, 4);
2474
2475 /* 1. The TCP pseudo-header */
2476 sg_set_buf(&sg[block++], &hp->md5_blk, bplen);
2477 nbytes += bplen;
2478
2479 /* 2. The TCP header, excluding options, and assuming a
2480 * checksum of zero
2481 */
2482 cksum = th->check;
2483 th->check = 0;
2484 sg_set_buf(&sg[block++], th, sizeof(*th));
2485 nbytes += sizeof(*th);
2486
2487 /* 3. The TCP segment data (if any) */
2488 data_len = tcplen - (th->doff << 2);
2489 if (data_len > 0) {
2490 u8 *data = (u8 *)th + (th->doff << 2);
2491 sg_set_buf(&sg[block++], data, data_len);
2492 nbytes += data_len;
2493 }
2494
2495 /* 4. an independently-specified key or password, known to both
2496 * TCPs and presumably connection-specific
2497 */
2498 sg_set_buf(&sg[block++], key->key, key->keylen);
2499 nbytes += key->keylen;
2500
2501 sg_mark_end(&sg[block - 1]);
2502
2503 /* Now store the hash into the packet */
2504 err = crypto_hash_init(desc);
2505 if (err) {
2506 if (net_ratelimit())
2507 printk(KERN_WARNING "%s(): hash_init failed\n", __func__);
2508 return -1;
2509 }
2510 err = crypto_hash_update(desc, sg, nbytes);
2511 if (err) {
2512 if (net_ratelimit())
2513 printk(KERN_WARNING "%s(): hash_update failed\n", __func__);
2514 return -1;
2515 }
2516 err = crypto_hash_final(desc, md5_hash);
2517 if (err) {
2518 if (net_ratelimit())
2519 printk(KERN_WARNING "%s(): hash_final failed\n", __func__);
2520 return -1;
2521 }
2522
2523 /* Reset header */
2524 th->check = cksum;
2525
2526 return 0;
2527}
2528EXPORT_SYMBOL(tcp_calc_md5_hash);
2529
2460static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool **pool) 2530static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool **pool)
2461{ 2531{
2462 int cpu; 2532 int cpu;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index b68c3c7d906b..bc7f62e2792b 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3448,6 +3448,43 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
3448 return 1; 3448 return 1;
3449} 3449}
3450 3450
3451#ifdef CONFIG_TCP_MD5SIG
3452/*
3453 * Parse MD5 Signature option
3454 */
3455u8 *tcp_parse_md5sig_option(struct tcphdr *th)
3456{
3457 int length = (th->doff << 2) - sizeof (*th);
3458 u8 *ptr = (u8*)(th + 1);
3459
3460 /* If the TCP option is too short, we can short cut */
3461 if (length < TCPOLEN_MD5SIG)
3462 return NULL;
3463
3464 while (length > 0) {
3465 int opcode = *ptr++;
3466 int opsize;
3467
3468 switch(opcode) {
3469 case TCPOPT_EOL:
3470 return NULL;
3471 case TCPOPT_NOP:
3472 length--;
3473 continue;
3474 default:
3475 opsize = *ptr++;
3476 if (opsize < 2 || opsize > length)
3477 return NULL;
3478 if (opcode == TCPOPT_MD5SIG)
3479 return ptr;
3480 }
3481 ptr += opsize - 2;
3482 length -= opsize;
3483 }
3484 return NULL;
3485}
3486#endif
3487
3451static inline void tcp_store_ts_recent(struct tcp_sock *tp) 3488static inline void tcp_store_ts_recent(struct tcp_sock *tp)
3452{ 3489{
3453 tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; 3490 tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
@@ -5465,6 +5502,9 @@ EXPORT_SYMBOL(sysctl_tcp_ecn);
5465EXPORT_SYMBOL(sysctl_tcp_reordering); 5502EXPORT_SYMBOL(sysctl_tcp_reordering);
5466EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); 5503EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
5467EXPORT_SYMBOL(tcp_parse_options); 5504EXPORT_SYMBOL(tcp_parse_options);
5505#ifdef CONFIG_TCP_MD5SIG
5506EXPORT_SYMBOL(tcp_parse_md5sig_option);
5507#endif
5468EXPORT_SYMBOL(tcp_rcv_established); 5508EXPORT_SYMBOL(tcp_rcv_established);
5469EXPORT_SYMBOL(tcp_rcv_state_process); 5509EXPORT_SYMBOL(tcp_rcv_state_process);
5470EXPORT_SYMBOL(tcp_initialize_rcv_mss); 5510EXPORT_SYMBOL(tcp_initialize_rcv_mss);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index f2926ae1de57..9088d709725e 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -93,8 +93,13 @@ static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk,
93 __be32 addr); 93 __be32 addr);
94static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 94static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
95 __be32 saddr, __be32 daddr, 95 __be32 saddr, __be32 daddr,
96 struct tcphdr *th, int protocol, 96 struct tcphdr *th, unsigned int tcplen);
97 unsigned int tcplen); 97#else
98static inline
99struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr)
100{
101 return NULL;
102}
98#endif 103#endif
99 104
100struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { 105struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
@@ -584,8 +589,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
584 key, 589 key,
585 ip_hdr(skb)->daddr, 590 ip_hdr(skb)->daddr,
586 ip_hdr(skb)->saddr, 591 ip_hdr(skb)->saddr,
587 &rep.th, IPPROTO_TCP, 592 &rep.th, arg.iov[0].iov_len);
588 arg.iov[0].iov_len);
589 } 593 }
590#endif 594#endif
591 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, 595 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
@@ -604,9 +608,9 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
604 outside socket context is ugly, certainly. What can I do? 608 outside socket context is ugly, certainly. What can I do?
605 */ 609 */
606 610
607static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, 611static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
608 struct sk_buff *skb, u32 seq, u32 ack, 612 u32 win, u32 ts, int oif,
609 u32 win, u32 ts) 613 struct tcp_md5sig_key *key)
610{ 614{
611 struct tcphdr *th = tcp_hdr(skb); 615 struct tcphdr *th = tcp_hdr(skb);
612 struct { 616 struct {
@@ -618,10 +622,6 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
618 ]; 622 ];
619 } rep; 623 } rep;
620 struct ip_reply_arg arg; 624 struct ip_reply_arg arg;
621#ifdef CONFIG_TCP_MD5SIG
622 struct tcp_md5sig_key *key;
623 struct tcp_md5sig_key tw_key;
624#endif
625 625
626 memset(&rep.th, 0, sizeof(struct tcphdr)); 626 memset(&rep.th, 0, sizeof(struct tcphdr));
627 memset(&arg, 0, sizeof(arg)); 627 memset(&arg, 0, sizeof(arg));
@@ -647,23 +647,6 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
647 rep.th.window = htons(win); 647 rep.th.window = htons(win);
648 648
649#ifdef CONFIG_TCP_MD5SIG 649#ifdef CONFIG_TCP_MD5SIG
650 /*
651 * The SKB holds an imcoming packet, but may not have a valid ->sk
652 * pointer. This is especially the case when we're dealing with a
653 * TIME_WAIT ack, because the sk structure is long gone, and only
654 * the tcp_timewait_sock remains. So the md5 key is stashed in that
655 * structure, and we use it in preference. I believe that (twsk ||
656 * skb->sk) holds true, but we program defensively.
657 */
658 if (!twsk && skb->sk) {
659 key = tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr);
660 } else if (twsk && twsk->tw_md5_keylen) {
661 tw_key.key = twsk->tw_md5_key;
662 tw_key.keylen = twsk->tw_md5_keylen;
663 key = &tw_key;
664 } else
665 key = NULL;
666
667 if (key) { 650 if (key) {
668 int offset = (ts) ? 3 : 0; 651 int offset = (ts) ? 3 : 0;
669 652
@@ -678,16 +661,15 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
678 key, 661 key,
679 ip_hdr(skb)->daddr, 662 ip_hdr(skb)->daddr,
680 ip_hdr(skb)->saddr, 663 ip_hdr(skb)->saddr,
681 &rep.th, IPPROTO_TCP, 664 &rep.th, arg.iov[0].iov_len);
682 arg.iov[0].iov_len);
683 } 665 }
684#endif 666#endif
685 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, 667 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
686 ip_hdr(skb)->saddr, /* XXX */ 668 ip_hdr(skb)->saddr, /* XXX */
687 arg.iov[0].iov_len, IPPROTO_TCP, 0); 669 arg.iov[0].iov_len, IPPROTO_TCP, 0);
688 arg.csumoffset = offsetof(struct tcphdr, check) / 2; 670 arg.csumoffset = offsetof(struct tcphdr, check) / 2;
689 if (twsk) 671 if (oif)
690 arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if; 672 arg.bound_dev_if = oif;
691 673
692 ip_send_reply(dev_net(skb->dev)->ipv4.tcp_sock, skb, 674 ip_send_reply(dev_net(skb->dev)->ipv4.tcp_sock, skb,
693 &arg, arg.iov[0].iov_len); 675 &arg, arg.iov[0].iov_len);
@@ -700,9 +682,12 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
700 struct inet_timewait_sock *tw = inet_twsk(sk); 682 struct inet_timewait_sock *tw = inet_twsk(sk);
701 struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 683 struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
702 684
703 tcp_v4_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 685 tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
704 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 686 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
705 tcptw->tw_ts_recent); 687 tcptw->tw_ts_recent,
688 tw->tw_bound_dev_if,
689 tcp_twsk_md5_key(tcptw)
690 );
706 691
707 inet_twsk_put(tw); 692 inet_twsk_put(tw);
708} 693}
@@ -710,9 +695,11 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
710static void tcp_v4_reqsk_send_ack(struct sk_buff *skb, 695static void tcp_v4_reqsk_send_ack(struct sk_buff *skb,
711 struct request_sock *req) 696 struct request_sock *req)
712{ 697{
713 tcp_v4_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, 698 tcp_v4_send_ack(skb, tcp_rsk(req)->snt_isn + 1,
714 tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, 699 tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
715 req->ts_recent); 700 req->ts_recent,
701 0,
702 tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr));
716} 703}
717 704
718/* 705/*
@@ -1004,18 +991,12 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
1004 991
1005static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 992static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1006 __be32 saddr, __be32 daddr, 993 __be32 saddr, __be32 daddr,
1007 struct tcphdr *th, int protocol, 994 struct tcphdr *th,
1008 unsigned int tcplen) 995 unsigned int tcplen)
1009{ 996{
1010 struct scatterlist sg[4];
1011 __u16 data_len;
1012 int block = 0;
1013 __sum16 old_checksum;
1014 struct tcp_md5sig_pool *hp; 997 struct tcp_md5sig_pool *hp;
1015 struct tcp4_pseudohdr *bp; 998 struct tcp4_pseudohdr *bp;
1016 struct hash_desc *desc;
1017 int err; 999 int err;
1018 unsigned int nbytes = 0;
1019 1000
1020 /* 1001 /*
1021 * Okay, so RFC2385 is turned on for this connection, 1002 * Okay, so RFC2385 is turned on for this connection,
@@ -1027,63 +1008,25 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1027 goto clear_hash_noput; 1008 goto clear_hash_noput;
1028 1009
1029 bp = &hp->md5_blk.ip4; 1010 bp = &hp->md5_blk.ip4;
1030 desc = &hp->md5_desc;
1031 1011
1032 /* 1012 /*
1033 * 1. the TCP pseudo-header (in the order: source IP address, 1013 * The TCP pseudo-header (in the order: source IP address,
1034 * destination IP address, zero-padded protocol number, and 1014 * destination IP address, zero-padded protocol number, and
1035 * segment length) 1015 * segment length)
1036 */ 1016 */
1037 bp->saddr = saddr; 1017 bp->saddr = saddr;
1038 bp->daddr = daddr; 1018 bp->daddr = daddr;
1039 bp->pad = 0; 1019 bp->pad = 0;
1040 bp->protocol = protocol; 1020 bp->protocol = IPPROTO_TCP;
1041 bp->len = htons(tcplen); 1021 bp->len = htons(tcplen);
1042 1022
1043 sg_init_table(sg, 4); 1023 err = tcp_calc_md5_hash(md5_hash, key, sizeof(*bp),
1044 1024 th, tcplen, hp);
1045 sg_set_buf(&sg[block++], bp, sizeof(*bp));
1046 nbytes += sizeof(*bp);
1047
1048 /* 2. the TCP header, excluding options, and assuming a
1049 * checksum of zero/
1050 */
1051 old_checksum = th->check;
1052 th->check = 0;
1053 sg_set_buf(&sg[block++], th, sizeof(struct tcphdr));
1054 nbytes += sizeof(struct tcphdr);
1055
1056 /* 3. the TCP segment data (if any) */
1057 data_len = tcplen - (th->doff << 2);
1058 if (data_len > 0) {
1059 unsigned char *data = (unsigned char *)th + (th->doff << 2);
1060 sg_set_buf(&sg[block++], data, data_len);
1061 nbytes += data_len;
1062 }
1063
1064 /* 4. an independently-specified key or password, known to both
1065 * TCPs and presumably connection-specific
1066 */
1067 sg_set_buf(&sg[block++], key->key, key->keylen);
1068 nbytes += key->keylen;
1069
1070 sg_mark_end(&sg[block - 1]);
1071
1072 /* Now store the Hash into the packet */
1073 err = crypto_hash_init(desc);
1074 if (err)
1075 goto clear_hash;
1076 err = crypto_hash_update(desc, sg, nbytes);
1077 if (err)
1078 goto clear_hash;
1079 err = crypto_hash_final(desc, md5_hash);
1080 if (err) 1025 if (err)
1081 goto clear_hash; 1026 goto clear_hash;
1082 1027
1083 /* Reset header, and free up the crypto */ 1028 /* Free up the crypto pool */
1084 tcp_put_md5sig_pool(); 1029 tcp_put_md5sig_pool();
1085 th->check = old_checksum;
1086
1087out: 1030out:
1088 return 0; 1031 return 0;
1089clear_hash: 1032clear_hash:
@@ -1097,7 +1040,7 @@ int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1097 struct sock *sk, 1040 struct sock *sk,
1098 struct dst_entry *dst, 1041 struct dst_entry *dst,
1099 struct request_sock *req, 1042 struct request_sock *req,
1100 struct tcphdr *th, int protocol, 1043 struct tcphdr *th,
1101 unsigned int tcplen) 1044 unsigned int tcplen)
1102{ 1045{
1103 __be32 saddr, daddr; 1046 __be32 saddr, daddr;
@@ -1113,7 +1056,7 @@ int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1113 } 1056 }
1114 return tcp_v4_do_calc_md5_hash(md5_hash, key, 1057 return tcp_v4_do_calc_md5_hash(md5_hash, key,
1115 saddr, daddr, 1058 saddr, daddr,
1116 th, protocol, tcplen); 1059 th, tcplen);
1117} 1060}
1118 1061
1119EXPORT_SYMBOL(tcp_v4_calc_md5_hash); 1062EXPORT_SYMBOL(tcp_v4_calc_md5_hash);
@@ -1132,52 +1075,12 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb)
1132 struct tcp_md5sig_key *hash_expected; 1075 struct tcp_md5sig_key *hash_expected;
1133 const struct iphdr *iph = ip_hdr(skb); 1076 const struct iphdr *iph = ip_hdr(skb);
1134 struct tcphdr *th = tcp_hdr(skb); 1077 struct tcphdr *th = tcp_hdr(skb);
1135 int length = (th->doff << 2) - sizeof(struct tcphdr);
1136 int genhash; 1078 int genhash;
1137 unsigned char *ptr;
1138 unsigned char newhash[16]; 1079 unsigned char newhash[16];
1139 1080
1140 hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr); 1081 hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr);
1082 hash_location = tcp_parse_md5sig_option(th);
1141 1083
1142 /*
1143 * If the TCP option length is less than the TCP_MD5SIG
1144 * option length, then we can shortcut
1145 */
1146 if (length < TCPOLEN_MD5SIG) {
1147 if (hash_expected)
1148 return 1;
1149 else
1150 return 0;
1151 }
1152
1153 /* Okay, we can't shortcut - we have to grub through the options */
1154 ptr = (unsigned char *)(th + 1);
1155 while (length > 0) {
1156 int opcode = *ptr++;
1157 int opsize;
1158
1159 switch (opcode) {
1160 case TCPOPT_EOL:
1161 goto done_opts;
1162 case TCPOPT_NOP:
1163 length--;
1164 continue;
1165 default:
1166 opsize = *ptr++;
1167 if (opsize < 2)
1168 goto done_opts;
1169 if (opsize > length)
1170 goto done_opts;
1171
1172 if (opcode == TCPOPT_MD5SIG) {
1173 hash_location = ptr;
1174 goto done_opts;
1175 }
1176 }
1177 ptr += opsize-2;
1178 length -= opsize;
1179 }
1180done_opts:
1181 /* We've parsed the options - do we have a hash? */ 1084 /* We've parsed the options - do we have a hash? */
1182 if (!hash_expected && !hash_location) 1085 if (!hash_expected && !hash_location)
1183 return 0; 1086 return 0;
@@ -1204,8 +1107,7 @@ done_opts:
1204 genhash = tcp_v4_do_calc_md5_hash(newhash, 1107 genhash = tcp_v4_do_calc_md5_hash(newhash,
1205 hash_expected, 1108 hash_expected,
1206 iph->saddr, iph->daddr, 1109 iph->saddr, iph->daddr,
1207 th, sk->sk_protocol, 1110 th, skb->len);
1208 skb->len);
1209 1111
1210 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 1112 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
1211 if (net_ratelimit()) { 1113 if (net_ratelimit()) {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index b171ac65ccab..8f83ab432705 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -605,7 +605,6 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
605 md5, 605 md5,
606 sk, NULL, NULL, 606 sk, NULL, NULL,
607 tcp_hdr(skb), 607 tcp_hdr(skb),
608 sk->sk_protocol,
609 skb->len); 608 skb->len);
610 } 609 }
611#endif 610#endif
@@ -2264,7 +2263,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2264 tp->af_specific->calc_md5_hash(md5_hash_location, 2263 tp->af_specific->calc_md5_hash(md5_hash_location,
2265 md5, 2264 md5,
2266 NULL, dst, req, 2265 NULL, dst, req,
2267 tcp_hdr(skb), sk->sk_protocol, 2266 tcp_hdr(skb),
2268 skb->len); 2267 skb->len);
2269 } 2268 }
2270#endif 2269#endif
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index deb38bf03376..9be6be3a7ff3 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -229,6 +229,12 @@ static inline int addrconf_qdisc_ok(struct net_device *dev)
229 return (dev->qdisc != &noop_qdisc); 229 return (dev->qdisc != &noop_qdisc);
230} 230}
231 231
232/* Check if a route is valid prefix route */
233static inline int addrconf_is_prefix_route(const struct rt6_info *rt)
234{
235 return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0);
236}
237
232static void addrconf_del_timer(struct inet6_ifaddr *ifp) 238static void addrconf_del_timer(struct inet6_ifaddr *ifp)
233{ 239{
234 if (del_timer(&ifp->timer)) 240 if (del_timer(&ifp->timer))
@@ -775,7 +781,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
775 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); 781 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
776 rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1); 782 rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1);
777 783
778 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 784 if (rt && addrconf_is_prefix_route(rt)) {
779 if (onlink == 0) { 785 if (onlink == 0) {
780 ip6_del_rt(rt); 786 ip6_del_rt(rt);
781 rt = NULL; 787 rt = NULL;
@@ -956,7 +962,8 @@ static inline int ipv6_saddr_preferred(int type)
956 return 0; 962 return 0;
957} 963}
958 964
959static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score, 965static int ipv6_get_saddr_eval(struct net *net,
966 struct ipv6_saddr_score *score,
960 struct ipv6_saddr_dst *dst, 967 struct ipv6_saddr_dst *dst,
961 int i) 968 int i)
962{ 969{
@@ -1035,7 +1042,8 @@ static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score,
1035 break; 1042 break;
1036 case IPV6_SADDR_RULE_LABEL: 1043 case IPV6_SADDR_RULE_LABEL:
1037 /* Rule 6: Prefer matching label */ 1044 /* Rule 6: Prefer matching label */
1038 ret = ipv6_addr_label(&score->ifa->addr, score->addr_type, 1045 ret = ipv6_addr_label(net,
1046 &score->ifa->addr, score->addr_type,
1039 score->ifa->idev->dev->ifindex) == dst->label; 1047 score->ifa->idev->dev->ifindex) == dst->label;
1040 break; 1048 break;
1041#ifdef CONFIG_IPV6_PRIVACY 1049#ifdef CONFIG_IPV6_PRIVACY
@@ -1089,7 +1097,7 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev,
1089 dst.addr = daddr; 1097 dst.addr = daddr;
1090 dst.ifindex = dst_dev ? dst_dev->ifindex : 0; 1098 dst.ifindex = dst_dev ? dst_dev->ifindex : 0;
1091 dst.scope = __ipv6_addr_src_scope(dst_type); 1099 dst.scope = __ipv6_addr_src_scope(dst_type);
1092 dst.label = ipv6_addr_label(daddr, dst_type, dst.ifindex); 1100 dst.label = ipv6_addr_label(net, daddr, dst_type, dst.ifindex);
1093 dst.prefs = prefs; 1101 dst.prefs = prefs;
1094 1102
1095 hiscore->rule = -1; 1103 hiscore->rule = -1;
@@ -1157,8 +1165,8 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev,
1157 for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) { 1165 for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) {
1158 int minihiscore, miniscore; 1166 int minihiscore, miniscore;
1159 1167
1160 minihiscore = ipv6_get_saddr_eval(hiscore, &dst, i); 1168 minihiscore = ipv6_get_saddr_eval(net, hiscore, &dst, i);
1161 miniscore = ipv6_get_saddr_eval(score, &dst, i); 1169 miniscore = ipv6_get_saddr_eval(net, score, &dst, i);
1162 1170
1163 if (minihiscore > miniscore) { 1171 if (minihiscore > miniscore) {
1164 if (i == IPV6_SADDR_RULE_SCOPE && 1172 if (i == IPV6_SADDR_RULE_SCOPE &&
@@ -1786,7 +1794,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
1786 rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, 1794 rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL,
1787 dev->ifindex, 1); 1795 dev->ifindex, 1);
1788 1796
1789 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 1797 if (rt && addrconf_is_prefix_route(rt)) {
1790 /* Autoconf prefix route */ 1798 /* Autoconf prefix route */
1791 if (valid_lft == 0) { 1799 if (valid_lft == 0) {
1792 ip6_del_rt(rt); 1800 ip6_del_rt(rt);
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 9bfa8846f262..08909039d87b 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -29,6 +29,9 @@
29 */ 29 */
30struct ip6addrlbl_entry 30struct ip6addrlbl_entry
31{ 31{
32#ifdef CONFIG_NET_NS
33 struct net *lbl_net;
34#endif
32 struct in6_addr prefix; 35 struct in6_addr prefix;
33 int prefixlen; 36 int prefixlen;
34 int ifindex; 37 int ifindex;
@@ -46,6 +49,16 @@ static struct ip6addrlbl_table
46 u32 seq; 49 u32 seq;
47} ip6addrlbl_table; 50} ip6addrlbl_table;
48 51
52static inline
53struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl)
54{
55#ifdef CONFIG_NET_NS
56 return lbl->lbl_net;
57#else
58 return &init_net;
59#endif
60}
61
49/* 62/*
50 * Default policy table (RFC3484 + extensions) 63 * Default policy table (RFC3484 + extensions)
51 * 64 *
@@ -65,7 +78,7 @@ static struct ip6addrlbl_table
65 78
66#define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL 79#define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL
67 80
68static const __initdata struct ip6addrlbl_init_table 81static const __net_initdata struct ip6addrlbl_init_table
69{ 82{
70 const struct in6_addr *prefix; 83 const struct in6_addr *prefix;
71 int prefixlen; 84 int prefixlen;
@@ -108,6 +121,9 @@ static const __initdata struct ip6addrlbl_init_table
108/* Object management */ 121/* Object management */
109static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p) 122static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p)
110{ 123{
124#ifdef CONFIG_NET_NS
125 release_net(p->lbl_net);
126#endif
111 kfree(p); 127 kfree(p);
112} 128}
113 129
@@ -128,10 +144,13 @@ static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p)
128} 144}
129 145
130/* Find label */ 146/* Find label */
131static int __ip6addrlbl_match(struct ip6addrlbl_entry *p, 147static int __ip6addrlbl_match(struct net *net,
148 struct ip6addrlbl_entry *p,
132 const struct in6_addr *addr, 149 const struct in6_addr *addr,
133 int addrtype, int ifindex) 150 int addrtype, int ifindex)
134{ 151{
152 if (!net_eq(ip6addrlbl_net(p), net))
153 return 0;
135 if (p->ifindex && p->ifindex != ifindex) 154 if (p->ifindex && p->ifindex != ifindex)
136 return 0; 155 return 0;
137 if (p->addrtype && p->addrtype != addrtype) 156 if (p->addrtype && p->addrtype != addrtype)
@@ -141,19 +160,21 @@ static int __ip6addrlbl_match(struct ip6addrlbl_entry *p,
141 return 1; 160 return 1;
142} 161}
143 162
144static struct ip6addrlbl_entry *__ipv6_addr_label(const struct in6_addr *addr, 163static struct ip6addrlbl_entry *__ipv6_addr_label(struct net *net,
164 const struct in6_addr *addr,
145 int type, int ifindex) 165 int type, int ifindex)
146{ 166{
147 struct hlist_node *pos; 167 struct hlist_node *pos;
148 struct ip6addrlbl_entry *p; 168 struct ip6addrlbl_entry *p;
149 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { 169 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
150 if (__ip6addrlbl_match(p, addr, type, ifindex)) 170 if (__ip6addrlbl_match(net, p, addr, type, ifindex))
151 return p; 171 return p;
152 } 172 }
153 return NULL; 173 return NULL;
154} 174}
155 175
156u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex) 176u32 ipv6_addr_label(struct net *net,
177 const struct in6_addr *addr, int type, int ifindex)
157{ 178{
158 u32 label; 179 u32 label;
159 struct ip6addrlbl_entry *p; 180 struct ip6addrlbl_entry *p;
@@ -161,7 +182,7 @@ u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex)
161 type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK; 182 type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK;
162 183
163 rcu_read_lock(); 184 rcu_read_lock();
164 p = __ipv6_addr_label(addr, type, ifindex); 185 p = __ipv6_addr_label(net, addr, type, ifindex);
165 label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT; 186 label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT;
166 rcu_read_unlock(); 187 rcu_read_unlock();
167 188
@@ -174,7 +195,8 @@ u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex)
174} 195}
175 196
176/* allocate one entry */ 197/* allocate one entry */
177static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix, 198static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net,
199 const struct in6_addr *prefix,
178 int prefixlen, int ifindex, 200 int prefixlen, int ifindex,
179 u32 label) 201 u32 label)
180{ 202{
@@ -216,6 +238,9 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix,
216 newp->addrtype = addrtype; 238 newp->addrtype = addrtype;
217 newp->label = label; 239 newp->label = label;
218 INIT_HLIST_NODE(&newp->list); 240 INIT_HLIST_NODE(&newp->list);
241#ifdef CONFIG_NET_NS
242 newp->lbl_net = hold_net(net);
243#endif
219 atomic_set(&newp->refcnt, 1); 244 atomic_set(&newp->refcnt, 1);
220 return newp; 245 return newp;
221} 246}
@@ -237,6 +262,7 @@ static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
237 hlist_for_each_entry_safe(p, pos, n, 262 hlist_for_each_entry_safe(p, pos, n,
238 &ip6addrlbl_table.head, list) { 263 &ip6addrlbl_table.head, list) {
239 if (p->prefixlen == newp->prefixlen && 264 if (p->prefixlen == newp->prefixlen &&
265 net_eq(ip6addrlbl_net(p), ip6addrlbl_net(newp)) &&
240 p->ifindex == newp->ifindex && 266 p->ifindex == newp->ifindex &&
241 ipv6_addr_equal(&p->prefix, &newp->prefix)) { 267 ipv6_addr_equal(&p->prefix, &newp->prefix)) {
242 if (!replace) { 268 if (!replace) {
@@ -261,7 +287,8 @@ out:
261} 287}
262 288
263/* add a label */ 289/* add a label */
264static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen, 290static int ip6addrlbl_add(struct net *net,
291 const struct in6_addr *prefix, int prefixlen,
265 int ifindex, u32 label, int replace) 292 int ifindex, u32 label, int replace)
266{ 293{
267 struct ip6addrlbl_entry *newp; 294 struct ip6addrlbl_entry *newp;
@@ -274,7 +301,7 @@ static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
274 (unsigned int)label, 301 (unsigned int)label,
275 replace); 302 replace);
276 303
277 newp = ip6addrlbl_alloc(prefix, prefixlen, ifindex, label); 304 newp = ip6addrlbl_alloc(net, prefix, prefixlen, ifindex, label);
278 if (IS_ERR(newp)) 305 if (IS_ERR(newp))
279 return PTR_ERR(newp); 306 return PTR_ERR(newp);
280 spin_lock(&ip6addrlbl_table.lock); 307 spin_lock(&ip6addrlbl_table.lock);
@@ -286,7 +313,8 @@ static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
286} 313}
287 314
288/* remove a label */ 315/* remove a label */
289static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, 316static int __ip6addrlbl_del(struct net *net,
317 const struct in6_addr *prefix, int prefixlen,
290 int ifindex) 318 int ifindex)
291{ 319{
292 struct ip6addrlbl_entry *p = NULL; 320 struct ip6addrlbl_entry *p = NULL;
@@ -300,6 +328,7 @@ static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
300 328
301 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) { 329 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) {
302 if (p->prefixlen == prefixlen && 330 if (p->prefixlen == prefixlen &&
331 net_eq(ip6addrlbl_net(p), net) &&
303 p->ifindex == ifindex && 332 p->ifindex == ifindex &&
304 ipv6_addr_equal(&p->prefix, prefix)) { 333 ipv6_addr_equal(&p->prefix, prefix)) {
305 hlist_del_rcu(&p->list); 334 hlist_del_rcu(&p->list);
@@ -311,7 +340,8 @@ static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
311 return ret; 340 return ret;
312} 341}
313 342
314static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, 343static int ip6addrlbl_del(struct net *net,
344 const struct in6_addr *prefix, int prefixlen,
315 int ifindex) 345 int ifindex)
316{ 346{
317 struct in6_addr prefix_buf; 347 struct in6_addr prefix_buf;
@@ -324,13 +354,13 @@ static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
324 354
325 ipv6_addr_prefix(&prefix_buf, prefix, prefixlen); 355 ipv6_addr_prefix(&prefix_buf, prefix, prefixlen);
326 spin_lock(&ip6addrlbl_table.lock); 356 spin_lock(&ip6addrlbl_table.lock);
327 ret = __ip6addrlbl_del(&prefix_buf, prefixlen, ifindex); 357 ret = __ip6addrlbl_del(net, &prefix_buf, prefixlen, ifindex);
328 spin_unlock(&ip6addrlbl_table.lock); 358 spin_unlock(&ip6addrlbl_table.lock);
329 return ret; 359 return ret;
330} 360}
331 361
332/* add default label */ 362/* add default label */
333static __init int ip6addrlbl_init(void) 363static int __net_init ip6addrlbl_net_init(struct net *net)
334{ 364{
335 int err = 0; 365 int err = 0;
336 int i; 366 int i;
@@ -338,7 +368,8 @@ static __init int ip6addrlbl_init(void)
338 ADDRLABEL(KERN_DEBUG "%s()\n", __func__); 368 ADDRLABEL(KERN_DEBUG "%s()\n", __func__);
339 369
340 for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) { 370 for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) {
341 int ret = ip6addrlbl_add(ip6addrlbl_init_table[i].prefix, 371 int ret = ip6addrlbl_add(net,
372 ip6addrlbl_init_table[i].prefix,
342 ip6addrlbl_init_table[i].prefixlen, 373 ip6addrlbl_init_table[i].prefixlen,
343 0, 374 0,
344 ip6addrlbl_init_table[i].label, 0); 375 ip6addrlbl_init_table[i].label, 0);
@@ -349,11 +380,32 @@ static __init int ip6addrlbl_init(void)
349 return err; 380 return err;
350} 381}
351 382
383static void __net_exit ip6addrlbl_net_exit(struct net *net)
384{
385 struct ip6addrlbl_entry *p = NULL;
386 struct hlist_node *pos, *n;
387
388 /* Remove all labels belonging to the exiting net */
389 spin_lock(&ip6addrlbl_table.lock);
390 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) {
391 if (net_eq(ip6addrlbl_net(p), net)) {
392 hlist_del_rcu(&p->list);
393 ip6addrlbl_put(p);
394 }
395 }
396 spin_unlock(&ip6addrlbl_table.lock);
397}
398
399static struct pernet_operations ipv6_addr_label_ops = {
400 .init = ip6addrlbl_net_init,
401 .exit = ip6addrlbl_net_exit,
402};
403
352int __init ipv6_addr_label_init(void) 404int __init ipv6_addr_label_init(void)
353{ 405{
354 spin_lock_init(&ip6addrlbl_table.lock); 406 spin_lock_init(&ip6addrlbl_table.lock);
355 407
356 return ip6addrlbl_init(); 408 return register_pernet_subsys(&ipv6_addr_label_ops);
357} 409}
358 410
359static const struct nla_policy ifal_policy[IFAL_MAX+1] = { 411static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
@@ -371,9 +423,6 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
371 u32 label; 423 u32 label;
372 int err = 0; 424 int err = 0;
373 425
374 if (net != &init_net)
375 return 0;
376
377 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 426 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
378 if (err < 0) 427 if (err < 0)
379 return err; 428 return err;
@@ -385,7 +434,7 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
385 return -EINVAL; 434 return -EINVAL;
386 435
387 if (ifal->ifal_index && 436 if (ifal->ifal_index &&
388 !__dev_get_by_index(&init_net, ifal->ifal_index)) 437 !__dev_get_by_index(net, ifal->ifal_index))
389 return -EINVAL; 438 return -EINVAL;
390 439
391 if (!tb[IFAL_ADDRESS]) 440 if (!tb[IFAL_ADDRESS])
@@ -403,12 +452,12 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
403 452
404 switch(nlh->nlmsg_type) { 453 switch(nlh->nlmsg_type) {
405 case RTM_NEWADDRLABEL: 454 case RTM_NEWADDRLABEL:
406 err = ip6addrlbl_add(pfx, ifal->ifal_prefixlen, 455 err = ip6addrlbl_add(net, pfx, ifal->ifal_prefixlen,
407 ifal->ifal_index, label, 456 ifal->ifal_index, label,
408 nlh->nlmsg_flags & NLM_F_REPLACE); 457 nlh->nlmsg_flags & NLM_F_REPLACE);
409 break; 458 break;
410 case RTM_DELADDRLABEL: 459 case RTM_DELADDRLABEL:
411 err = ip6addrlbl_del(pfx, ifal->ifal_prefixlen, 460 err = ip6addrlbl_del(net, pfx, ifal->ifal_prefixlen,
412 ifal->ifal_index); 461 ifal->ifal_index);
413 break; 462 break;
414 default: 463 default:
@@ -458,12 +507,10 @@ static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
458 int idx = 0, s_idx = cb->args[0]; 507 int idx = 0, s_idx = cb->args[0];
459 int err; 508 int err;
460 509
461 if (net != &init_net)
462 return 0;
463
464 rcu_read_lock(); 510 rcu_read_lock();
465 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { 511 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
466 if (idx >= s_idx) { 512 if (idx >= s_idx &&
513 net_eq(ip6addrlbl_net(p), net)) {
467 if ((err = ip6addrlbl_fill(skb, p, 514 if ((err = ip6addrlbl_fill(skb, p,
468 ip6addrlbl_table.seq, 515 ip6addrlbl_table.seq,
469 NETLINK_CB(cb->skb).pid, 516 NETLINK_CB(cb->skb).pid,
@@ -499,9 +546,6 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
499 struct ip6addrlbl_entry *p; 546 struct ip6addrlbl_entry *p;
500 struct sk_buff *skb; 547 struct sk_buff *skb;
501 548
502 if (net != &init_net)
503 return 0;
504
505 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 549 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
506 if (err < 0) 550 if (err < 0)
507 return err; 551 return err;
@@ -513,7 +557,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
513 return -EINVAL; 557 return -EINVAL;
514 558
515 if (ifal->ifal_index && 559 if (ifal->ifal_index &&
516 !__dev_get_by_index(&init_net, ifal->ifal_index)) 560 !__dev_get_by_index(net, ifal->ifal_index))
517 return -EINVAL; 561 return -EINVAL;
518 562
519 if (!tb[IFAL_ADDRESS]) 563 if (!tb[IFAL_ADDRESS])
@@ -524,7 +568,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
524 return -EINVAL; 568 return -EINVAL;
525 569
526 rcu_read_lock(); 570 rcu_read_lock();
527 p = __ipv6_addr_label(addr, ipv6_addr_type(addr), ifal->ifal_index); 571 p = __ipv6_addr_label(net, addr, ipv6_addr_type(addr), ifal->ifal_index);
528 if (p && ip6addrlbl_hold(p)) 572 if (p && ip6addrlbl_hold(p))
529 p = NULL; 573 p = NULL;
530 lseq = ip6addrlbl_table.seq; 574 lseq = ip6addrlbl_table.seq;
@@ -552,7 +596,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
552 goto out; 596 goto out;
553 } 597 }
554 598
555 err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); 599 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
556out: 600out:
557 return err; 601 return err;
558} 602}
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index bf268b386963..0b11b378d89a 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1240,7 +1240,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int
1240 1240
1241#endif 1241#endif
1242 /* 1242 /*
1243 * Spurious command, or MRT_VERSION which you cannot 1243 * Spurious command, or MRT6_VERSION which you cannot
1244 * set. 1244 * set.
1245 */ 1245 */
1246 default: 1246 default:
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index fbb2d12c41bc..bd2fe4cfafa7 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -162,7 +162,6 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
162 ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \ 162 ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \
163 (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp)))) 163 (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp))))
164 164
165#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
166#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) 165#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
167 166
168#define IPV6_MLD_MAX_MSF 64 167#define IPV6_MLD_MAX_MSF 64
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 155499197fc5..3fe736bead96 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -80,6 +80,12 @@ static struct inet_connection_sock_af_ops ipv6_specific;
80#ifdef CONFIG_TCP_MD5SIG 80#ifdef CONFIG_TCP_MD5SIG
81static struct tcp_sock_af_ops tcp_sock_ipv6_specific; 81static struct tcp_sock_af_ops tcp_sock_ipv6_specific;
82static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; 82static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
83#else
84static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
85 struct in6_addr *addr)
86{
87 return NULL;
88}
83#endif 89#endif
84 90
85static void tcp_v6_hash(struct sock *sk) 91static void tcp_v6_hash(struct sock *sk)
@@ -734,78 +740,34 @@ static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
734static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 740static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
735 struct in6_addr *saddr, 741 struct in6_addr *saddr,
736 struct in6_addr *daddr, 742 struct in6_addr *daddr,
737 struct tcphdr *th, int protocol, 743 struct tcphdr *th, unsigned int tcplen)
738 unsigned int tcplen)
739{ 744{
740 struct scatterlist sg[4];
741 __u16 data_len;
742 int block = 0;
743 __sum16 cksum;
744 struct tcp_md5sig_pool *hp; 745 struct tcp_md5sig_pool *hp;
745 struct tcp6_pseudohdr *bp; 746 struct tcp6_pseudohdr *bp;
746 struct hash_desc *desc;
747 int err; 747 int err;
748 unsigned int nbytes = 0;
749 748
750 hp = tcp_get_md5sig_pool(); 749 hp = tcp_get_md5sig_pool();
751 if (!hp) { 750 if (!hp) {
752 printk(KERN_WARNING "%s(): hash pool not found...\n", __func__); 751 printk(KERN_WARNING "%s(): hash pool not found...\n", __func__);
753 goto clear_hash_noput; 752 goto clear_hash_noput;
754 } 753 }
754
755 bp = &hp->md5_blk.ip6; 755 bp = &hp->md5_blk.ip6;
756 desc = &hp->md5_desc;
757 756
758 /* 1. TCP pseudo-header (RFC2460) */ 757 /* 1. TCP pseudo-header (RFC2460) */
759 ipv6_addr_copy(&bp->saddr, saddr); 758 ipv6_addr_copy(&bp->saddr, saddr);
760 ipv6_addr_copy(&bp->daddr, daddr); 759 ipv6_addr_copy(&bp->daddr, daddr);
761 bp->len = htonl(tcplen); 760 bp->len = htonl(tcplen);
762 bp->protocol = htonl(protocol); 761 bp->protocol = htonl(IPPROTO_TCP);
763
764 sg_init_table(sg, 4);
765 762
766 sg_set_buf(&sg[block++], bp, sizeof(*bp)); 763 err = tcp_calc_md5_hash(md5_hash, key, sizeof(*bp),
767 nbytes += sizeof(*bp); 764 th, tcplen, hp);
768 765
769 /* 2. TCP header, excluding options */ 766 if (err)
770 cksum = th->check;
771 th->check = 0;
772 sg_set_buf(&sg[block++], th, sizeof(*th));
773 nbytes += sizeof(*th);
774
775 /* 3. TCP segment data (if any) */
776 data_len = tcplen - (th->doff << 2);
777 if (data_len > 0) {
778 u8 *data = (u8 *)th + (th->doff << 2);
779 sg_set_buf(&sg[block++], data, data_len);
780 nbytes += data_len;
781 }
782
783 /* 4. shared key */
784 sg_set_buf(&sg[block++], key->key, key->keylen);
785 nbytes += key->keylen;
786
787 sg_mark_end(&sg[block - 1]);
788
789 /* Now store the hash into the packet */
790 err = crypto_hash_init(desc);
791 if (err) {
792 printk(KERN_WARNING "%s(): hash_init failed\n", __func__);
793 goto clear_hash;
794 }
795 err = crypto_hash_update(desc, sg, nbytes);
796 if (err) {
797 printk(KERN_WARNING "%s(): hash_update failed\n", __func__);
798 goto clear_hash;
799 }
800 err = crypto_hash_final(desc, md5_hash);
801 if (err) {
802 printk(KERN_WARNING "%s(): hash_final failed\n", __func__);
803 goto clear_hash; 767 goto clear_hash;
804 }
805 768
806 /* Reset header, and free up the crypto */ 769 /* Free up the crypto pool */
807 tcp_put_md5sig_pool(); 770 tcp_put_md5sig_pool();
808 th->check = cksum;
809out: 771out:
810 return 0; 772 return 0;
811clear_hash: 773clear_hash:
@@ -819,8 +781,7 @@ static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
819 struct sock *sk, 781 struct sock *sk,
820 struct dst_entry *dst, 782 struct dst_entry *dst,
821 struct request_sock *req, 783 struct request_sock *req,
822 struct tcphdr *th, int protocol, 784 struct tcphdr *th, unsigned int tcplen)
823 unsigned int tcplen)
824{ 785{
825 struct in6_addr *saddr, *daddr; 786 struct in6_addr *saddr, *daddr;
826 787
@@ -833,7 +794,7 @@ static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
833 } 794 }
834 return tcp_v6_do_calc_md5_hash(md5_hash, key, 795 return tcp_v6_do_calc_md5_hash(md5_hash, key,
835 saddr, daddr, 796 saddr, daddr,
836 th, protocol, tcplen); 797 th, tcplen);
837} 798}
838 799
839static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) 800static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
@@ -842,43 +803,12 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
842 struct tcp_md5sig_key *hash_expected; 803 struct tcp_md5sig_key *hash_expected;
843 struct ipv6hdr *ip6h = ipv6_hdr(skb); 804 struct ipv6hdr *ip6h = ipv6_hdr(skb);
844 struct tcphdr *th = tcp_hdr(skb); 805 struct tcphdr *th = tcp_hdr(skb);
845 int length = (th->doff << 2) - sizeof (*th);
846 int genhash; 806 int genhash;
847 u8 *ptr;
848 u8 newhash[16]; 807 u8 newhash[16];
849 808
850 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); 809 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr);
810 hash_location = tcp_parse_md5sig_option(th);
851 811
852 /* If the TCP option is too short, we can short cut */
853 if (length < TCPOLEN_MD5SIG)
854 return hash_expected ? 1 : 0;
855
856 /* parse options */
857 ptr = (u8*)(th + 1);
858 while (length > 0) {
859 int opcode = *ptr++;
860 int opsize;
861
862 switch(opcode) {
863 case TCPOPT_EOL:
864 goto done_opts;
865 case TCPOPT_NOP:
866 length--;
867 continue;
868 default:
869 opsize = *ptr++;
870 if (opsize < 2 || opsize > length)
871 goto done_opts;
872 if (opcode == TCPOPT_MD5SIG) {
873 hash_location = ptr;
874 goto done_opts;
875 }
876 }
877 ptr += opsize - 2;
878 length -= opsize;
879 }
880
881done_opts:
882 /* do we have a hash as expected? */ 812 /* do we have a hash as expected? */
883 if (!hash_expected) { 813 if (!hash_expected) {
884 if (!hash_location) 814 if (!hash_location)
@@ -908,8 +838,7 @@ done_opts:
908 genhash = tcp_v6_do_calc_md5_hash(newhash, 838 genhash = tcp_v6_do_calc_md5_hash(newhash,
909 hash_expected, 839 hash_expected,
910 &ip6h->saddr, &ip6h->daddr, 840 &ip6h->saddr, &ip6h->daddr,
911 th, sk->sk_protocol, 841 th, skb->len);
912 skb->len);
913 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 842 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
914 if (net_ratelimit()) { 843 if (net_ratelimit()) {
915 printk(KERN_INFO "MD5 Hash %s for " 844 printk(KERN_INFO "MD5 Hash %s for "
@@ -1049,7 +978,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1049 tcp_v6_do_calc_md5_hash((__u8 *)&opt[1], key, 978 tcp_v6_do_calc_md5_hash((__u8 *)&opt[1], key,
1050 &ipv6_hdr(skb)->daddr, 979 &ipv6_hdr(skb)->daddr,
1051 &ipv6_hdr(skb)->saddr, 980 &ipv6_hdr(skb)->saddr,
1052 t1, IPPROTO_TCP, tot_len); 981 t1, tot_len);
1053 } 982 }
1054#endif 983#endif
1055 984
@@ -1086,8 +1015,8 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1086 kfree_skb(buff); 1015 kfree_skb(buff);
1087} 1016}
1088 1017
1089static void tcp_v6_send_ack(struct tcp_timewait_sock *tw, 1018static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
1090 struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts) 1019 struct tcp_md5sig_key *key)
1091{ 1020{
1092 struct tcphdr *th = tcp_hdr(skb), *t1; 1021 struct tcphdr *th = tcp_hdr(skb), *t1;
1093 struct sk_buff *buff; 1022 struct sk_buff *buff;
@@ -1096,22 +1025,6 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1096 struct sock *ctl_sk = net->ipv6.tcp_sk; 1025 struct sock *ctl_sk = net->ipv6.tcp_sk;
1097 unsigned int tot_len = sizeof(struct tcphdr); 1026 unsigned int tot_len = sizeof(struct tcphdr);
1098 __be32 *topt; 1027 __be32 *topt;
1099#ifdef CONFIG_TCP_MD5SIG
1100 struct tcp_md5sig_key *key;
1101 struct tcp_md5sig_key tw_key;
1102#endif
1103
1104#ifdef CONFIG_TCP_MD5SIG
1105 if (!tw && skb->sk) {
1106 key = tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr);
1107 } else if (tw && tw->tw_md5_keylen) {
1108 tw_key.key = tw->tw_md5_key;
1109 tw_key.keylen = tw->tw_md5_keylen;
1110 key = &tw_key;
1111 } else {
1112 key = NULL;
1113 }
1114#endif
1115 1028
1116 if (ts) 1029 if (ts)
1117 tot_len += TCPOLEN_TSTAMP_ALIGNED; 1030 tot_len += TCPOLEN_TSTAMP_ALIGNED;
@@ -1155,7 +1068,7 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1155 tcp_v6_do_calc_md5_hash((__u8 *)topt, key, 1068 tcp_v6_do_calc_md5_hash((__u8 *)topt, key,
1156 &ipv6_hdr(skb)->daddr, 1069 &ipv6_hdr(skb)->daddr,
1157 &ipv6_hdr(skb)->saddr, 1070 &ipv6_hdr(skb)->saddr,
1158 t1, IPPROTO_TCP, tot_len); 1071 t1, tot_len);
1159 } 1072 }
1160#endif 1073#endif
1161 1074
@@ -1191,16 +1104,17 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
1191 struct inet_timewait_sock *tw = inet_twsk(sk); 1104 struct inet_timewait_sock *tw = inet_twsk(sk);
1192 struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 1105 struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
1193 1106
1194 tcp_v6_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 1107 tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
1195 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 1108 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
1196 tcptw->tw_ts_recent); 1109 tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw));
1197 1110
1198 inet_twsk_put(tw); 1111 inet_twsk_put(tw);
1199} 1112}
1200 1113
1201static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) 1114static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
1202{ 1115{
1203 tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent); 1116 tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent,
1117 tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr));
1204} 1118}
1205 1119
1206 1120
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 9bba7ac5fee0..841af9f2d5e0 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -579,25 +579,43 @@ static uint8_t pfkey_proto_from_xfrm(uint8_t proto)
579 return (proto ? proto : IPSEC_PROTO_ANY); 579 return (proto ? proto : IPSEC_PROTO_ANY);
580} 580}
581 581
582static int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, 582static inline int pfkey_sockaddr_len(sa_family_t family)
583 xfrm_address_t *xaddr)
584{ 583{
585 switch (((struct sockaddr*)(addr + 1))->sa_family) { 584 switch (family) {
585 case AF_INET:
586 return sizeof(struct sockaddr_in);
587#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
588 case AF_INET6:
589 return sizeof(struct sockaddr_in6);
590#endif
591 }
592 return 0;
593}
594
595static
596int pfkey_sockaddr_extract(const struct sockaddr *sa, xfrm_address_t *xaddr)
597{
598 switch (sa->sa_family) {
586 case AF_INET: 599 case AF_INET:
587 xaddr->a4 = 600 xaddr->a4 =
588 ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr; 601 ((struct sockaddr_in *)sa)->sin_addr.s_addr;
589 return AF_INET; 602 return AF_INET;
590#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 603#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
591 case AF_INET6: 604 case AF_INET6:
592 memcpy(xaddr->a6, 605 memcpy(xaddr->a6,
593 &((struct sockaddr_in6 *)(addr + 1))->sin6_addr, 606 &((struct sockaddr_in6 *)sa)->sin6_addr,
594 sizeof(struct in6_addr)); 607 sizeof(struct in6_addr));
595 return AF_INET6; 608 return AF_INET6;
596#endif 609#endif
597 default:
598 return 0;
599 } 610 }
600 /* NOTREACHED */ 611 return 0;
612}
613
614static
615int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, xfrm_address_t *xaddr)
616{
617 return pfkey_sockaddr_extract((struct sockaddr *)(addr + 1),
618 xaddr);
601} 619}
602 620
603static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs) 621static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs)
@@ -642,20 +660,11 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **
642} 660}
643 661
644#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) 662#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
663
645static int 664static int
646pfkey_sockaddr_size(sa_family_t family) 665pfkey_sockaddr_size(sa_family_t family)
647{ 666{
648 switch (family) { 667 return PFKEY_ALIGN8(pfkey_sockaddr_len(family));
649 case AF_INET:
650 return PFKEY_ALIGN8(sizeof(struct sockaddr_in));
651#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
652 case AF_INET6:
653 return PFKEY_ALIGN8(sizeof(struct sockaddr_in6));
654#endif
655 default:
656 return 0;
657 }
658 /* NOTREACHED */
659} 668}
660 669
661static inline int pfkey_mode_from_xfrm(int mode) 670static inline int pfkey_mode_from_xfrm(int mode)
@@ -687,6 +696,36 @@ static inline int pfkey_mode_to_xfrm(int mode)
687 } 696 }
688} 697}
689 698
699static unsigned int pfkey_sockaddr_fill(xfrm_address_t *xaddr, __be16 port,
700 struct sockaddr *sa,
701 unsigned short family)
702{
703 switch (family) {
704 case AF_INET:
705 {
706 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
707 sin->sin_family = AF_INET;
708 sin->sin_port = port;
709 sin->sin_addr.s_addr = xaddr->a4;
710 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
711 return 32;
712 }
713#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
714 case AF_INET6:
715 {
716 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
717 sin6->sin6_family = AF_INET6;
718 sin6->sin6_port = port;
719 sin6->sin6_flowinfo = 0;
720 ipv6_addr_copy(&sin6->sin6_addr, (struct in6_addr *)xaddr->a6);
721 sin6->sin6_scope_id = 0;
722 return 128;
723 }
724#endif
725 }
726 return 0;
727}
728
690static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, 729static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
691 int add_keys, int hsc) 730 int add_keys, int hsc)
692{ 731{
@@ -697,13 +736,9 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
697 struct sadb_address *addr; 736 struct sadb_address *addr;
698 struct sadb_key *key; 737 struct sadb_key *key;
699 struct sadb_x_sa2 *sa2; 738 struct sadb_x_sa2 *sa2;
700 struct sockaddr_in *sin;
701 struct sadb_x_sec_ctx *sec_ctx; 739 struct sadb_x_sec_ctx *sec_ctx;
702 struct xfrm_sec_ctx *xfrm_ctx; 740 struct xfrm_sec_ctx *xfrm_ctx;
703 int ctx_size = 0; 741 int ctx_size = 0;
704#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
705 struct sockaddr_in6 *sin6;
706#endif
707 int size; 742 int size;
708 int auth_key_size = 0; 743 int auth_key_size = 0;
709 int encrypt_key_size = 0; 744 int encrypt_key_size = 0;
@@ -732,14 +767,7 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
732 } 767 }
733 768
734 /* identity & sensitivity */ 769 /* identity & sensitivity */
735 770 if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr, x->props.family))
736 if ((x->props.family == AF_INET &&
737 x->sel.saddr.a4 != x->props.saddr.a4)
738#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
739 || (x->props.family == AF_INET6 &&
740 memcmp (x->sel.saddr.a6, x->props.saddr.a6, sizeof (struct in6_addr)))
741#endif
742 )
743 size += sizeof(struct sadb_address) + sockaddr_size; 771 size += sizeof(struct sadb_address) + sockaddr_size;
744 772
745 if (add_keys) { 773 if (add_keys) {
@@ -861,29 +889,12 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
861 protocol's number." - RFC2367 */ 889 protocol's number." - RFC2367 */
862 addr->sadb_address_proto = 0; 890 addr->sadb_address_proto = 0;
863 addr->sadb_address_reserved = 0; 891 addr->sadb_address_reserved = 0;
864 if (x->props.family == AF_INET) {
865 addr->sadb_address_prefixlen = 32;
866 892
867 sin = (struct sockaddr_in *) (addr + 1); 893 addr->sadb_address_prefixlen =
868 sin->sin_family = AF_INET; 894 pfkey_sockaddr_fill(&x->props.saddr, 0,
869 sin->sin_addr.s_addr = x->props.saddr.a4; 895 (struct sockaddr *) (addr + 1),
870 sin->sin_port = 0; 896 x->props.family);
871 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 897 if (!addr->sadb_address_prefixlen)
872 }
873#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
874 else if (x->props.family == AF_INET6) {
875 addr->sadb_address_prefixlen = 128;
876
877 sin6 = (struct sockaddr_in6 *) (addr + 1);
878 sin6->sin6_family = AF_INET6;
879 sin6->sin6_port = 0;
880 sin6->sin6_flowinfo = 0;
881 memcpy(&sin6->sin6_addr, x->props.saddr.a6,
882 sizeof(struct in6_addr));
883 sin6->sin6_scope_id = 0;
884 }
885#endif
886 else
887 BUG(); 898 BUG();
888 899
889 /* dst address */ 900 /* dst address */
@@ -894,70 +905,32 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
894 sizeof(uint64_t); 905 sizeof(uint64_t);
895 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 906 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
896 addr->sadb_address_proto = 0; 907 addr->sadb_address_proto = 0;
897 addr->sadb_address_prefixlen = 32; /* XXX */
898 addr->sadb_address_reserved = 0; 908 addr->sadb_address_reserved = 0;
899 if (x->props.family == AF_INET) {
900 sin = (struct sockaddr_in *) (addr + 1);
901 sin->sin_family = AF_INET;
902 sin->sin_addr.s_addr = x->id.daddr.a4;
903 sin->sin_port = 0;
904 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
905 909
906 if (x->sel.saddr.a4 != x->props.saddr.a4) { 910 addr->sadb_address_prefixlen =
907 addr = (struct sadb_address*) skb_put(skb, 911 pfkey_sockaddr_fill(&x->id.daddr, 0,
908 sizeof(struct sadb_address)+sockaddr_size); 912 (struct sockaddr *) (addr + 1),
909 addr->sadb_address_len = 913 x->props.family);
910 (sizeof(struct sadb_address)+sockaddr_size)/ 914 if (!addr->sadb_address_prefixlen)
911 sizeof(uint64_t); 915 BUG();
912 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
913 addr->sadb_address_proto =
914 pfkey_proto_from_xfrm(x->sel.proto);
915 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
916 addr->sadb_address_reserved = 0;
917
918 sin = (struct sockaddr_in *) (addr + 1);
919 sin->sin_family = AF_INET;
920 sin->sin_addr.s_addr = x->sel.saddr.a4;
921 sin->sin_port = x->sel.sport;
922 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
923 }
924 }
925#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
926 else if (x->props.family == AF_INET6) {
927 addr->sadb_address_prefixlen = 128;
928 916
929 sin6 = (struct sockaddr_in6 *) (addr + 1); 917 if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr,
930 sin6->sin6_family = AF_INET6; 918 x->props.family)) {
931 sin6->sin6_port = 0; 919 addr = (struct sadb_address*) skb_put(skb,
932 sin6->sin6_flowinfo = 0; 920 sizeof(struct sadb_address)+sockaddr_size);
933 memcpy(&sin6->sin6_addr, x->id.daddr.a6, sizeof(struct in6_addr)); 921 addr->sadb_address_len =
934 sin6->sin6_scope_id = 0; 922 (sizeof(struct sadb_address)+sockaddr_size)/
923 sizeof(uint64_t);
924 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
925 addr->sadb_address_proto =
926 pfkey_proto_from_xfrm(x->sel.proto);
927 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
928 addr->sadb_address_reserved = 0;
935 929
936 if (memcmp (x->sel.saddr.a6, x->props.saddr.a6, 930 pfkey_sockaddr_fill(&x->sel.saddr, x->sel.sport,
937 sizeof(struct in6_addr))) { 931 (struct sockaddr *) (addr + 1),
938 addr = (struct sadb_address *) skb_put(skb, 932 x->props.family);
939 sizeof(struct sadb_address)+sockaddr_size);
940 addr->sadb_address_len =
941 (sizeof(struct sadb_address)+sockaddr_size)/
942 sizeof(uint64_t);
943 addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
944 addr->sadb_address_proto =
945 pfkey_proto_from_xfrm(x->sel.proto);
946 addr->sadb_address_prefixlen = x->sel.prefixlen_s;
947 addr->sadb_address_reserved = 0;
948
949 sin6 = (struct sockaddr_in6 *) (addr + 1);
950 sin6->sin6_family = AF_INET6;
951 sin6->sin6_port = x->sel.sport;
952 sin6->sin6_flowinfo = 0;
953 memcpy(&sin6->sin6_addr, x->sel.saddr.a6,
954 sizeof(struct in6_addr));
955 sin6->sin6_scope_id = 0;
956 }
957 } 933 }
958#endif
959 else
960 BUG();
961 934
962 /* auth key */ 935 /* auth key */
963 if (add_keys && auth_key_size) { 936 if (add_keys && auth_key_size) {
@@ -1853,10 +1826,6 @@ static int
1853parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) 1826parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1854{ 1827{
1855 struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; 1828 struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr;
1856 struct sockaddr_in *sin;
1857#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1858 struct sockaddr_in6 *sin6;
1859#endif
1860 int mode; 1829 int mode;
1861 1830
1862 if (xp->xfrm_nr >= XFRM_MAX_DEPTH) 1831 if (xp->xfrm_nr >= XFRM_MAX_DEPTH)
@@ -1881,31 +1850,19 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1881 1850
1882 /* addresses present only in tunnel mode */ 1851 /* addresses present only in tunnel mode */
1883 if (t->mode == XFRM_MODE_TUNNEL) { 1852 if (t->mode == XFRM_MODE_TUNNEL) {
1884 struct sockaddr *sa; 1853 u8 *sa = (u8 *) (rq + 1);
1885 sa = (struct sockaddr *)(rq+1); 1854 int family, socklen;
1886 switch(sa->sa_family) { 1855
1887 case AF_INET: 1856 family = pfkey_sockaddr_extract((struct sockaddr *)sa,
1888 sin = (struct sockaddr_in*)sa; 1857 &t->saddr);
1889 t->saddr.a4 = sin->sin_addr.s_addr; 1858 if (!family)
1890 sin++;
1891 if (sin->sin_family != AF_INET)
1892 return -EINVAL;
1893 t->id.daddr.a4 = sin->sin_addr.s_addr;
1894 break;
1895#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1896 case AF_INET6:
1897 sin6 = (struct sockaddr_in6*)sa;
1898 memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
1899 sin6++;
1900 if (sin6->sin6_family != AF_INET6)
1901 return -EINVAL;
1902 memcpy(t->id.daddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
1903 break;
1904#endif
1905 default:
1906 return -EINVAL; 1859 return -EINVAL;
1907 } 1860
1908 t->encap_family = sa->sa_family; 1861 socklen = pfkey_sockaddr_len(family);
1862 if (pfkey_sockaddr_extract((struct sockaddr *)(sa + socklen),
1863 &t->id.daddr) != family)
1864 return -EINVAL;
1865 t->encap_family = family;
1909 } else 1866 } else
1910 t->encap_family = xp->family; 1867 t->encap_family = xp->family;
1911 1868
@@ -1952,9 +1909,7 @@ static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
1952 1909
1953 for (i=0; i<xp->xfrm_nr; i++) { 1910 for (i=0; i<xp->xfrm_nr; i++) {
1954 t = xp->xfrm_vec + i; 1911 t = xp->xfrm_vec + i;
1955 socklen += (t->encap_family == AF_INET ? 1912 socklen += pfkey_sockaddr_len(t->encap_family);
1956 sizeof(struct sockaddr_in) :
1957 sizeof(struct sockaddr_in6));
1958 } 1913 }
1959 1914
1960 return sizeof(struct sadb_msg) + 1915 return sizeof(struct sadb_msg) +
@@ -1987,18 +1942,12 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
1987 struct sadb_address *addr; 1942 struct sadb_address *addr;
1988 struct sadb_lifetime *lifetime; 1943 struct sadb_lifetime *lifetime;
1989 struct sadb_x_policy *pol; 1944 struct sadb_x_policy *pol;
1990 struct sockaddr_in *sin;
1991 struct sadb_x_sec_ctx *sec_ctx; 1945 struct sadb_x_sec_ctx *sec_ctx;
1992 struct xfrm_sec_ctx *xfrm_ctx; 1946 struct xfrm_sec_ctx *xfrm_ctx;
1993#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1994 struct sockaddr_in6 *sin6;
1995#endif
1996 int i; 1947 int i;
1997 int size; 1948 int size;
1998 int sockaddr_size = pfkey_sockaddr_size(xp->family); 1949 int sockaddr_size = pfkey_sockaddr_size(xp->family);
1999 int socklen = (xp->family == AF_INET ? 1950 int socklen = pfkey_sockaddr_len(xp->family);
2000 sizeof(struct sockaddr_in) :
2001 sizeof(struct sockaddr_in6));
2002 1951
2003 size = pfkey_xfrm_policy2msg_size(xp); 1952 size = pfkey_xfrm_policy2msg_size(xp);
2004 1953
@@ -2016,26 +1965,10 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2016 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); 1965 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
2017 addr->sadb_address_prefixlen = xp->selector.prefixlen_s; 1966 addr->sadb_address_prefixlen = xp->selector.prefixlen_s;
2018 addr->sadb_address_reserved = 0; 1967 addr->sadb_address_reserved = 0;
2019 /* src address */ 1968 if (!pfkey_sockaddr_fill(&xp->selector.saddr,
2020 if (xp->family == AF_INET) { 1969 xp->selector.sport,
2021 sin = (struct sockaddr_in *) (addr + 1); 1970 (struct sockaddr *) (addr + 1),
2022 sin->sin_family = AF_INET; 1971 xp->family))
2023 sin->sin_addr.s_addr = xp->selector.saddr.a4;
2024 sin->sin_port = xp->selector.sport;
2025 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
2026 }
2027#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2028 else if (xp->family == AF_INET6) {
2029 sin6 = (struct sockaddr_in6 *) (addr + 1);
2030 sin6->sin6_family = AF_INET6;
2031 sin6->sin6_port = xp->selector.sport;
2032 sin6->sin6_flowinfo = 0;
2033 memcpy(&sin6->sin6_addr, xp->selector.saddr.a6,
2034 sizeof(struct in6_addr));
2035 sin6->sin6_scope_id = 0;
2036 }
2037#endif
2038 else
2039 BUG(); 1972 BUG();
2040 1973
2041 /* dst address */ 1974 /* dst address */
@@ -2048,26 +1981,10 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2048 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); 1981 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
2049 addr->sadb_address_prefixlen = xp->selector.prefixlen_d; 1982 addr->sadb_address_prefixlen = xp->selector.prefixlen_d;
2050 addr->sadb_address_reserved = 0; 1983 addr->sadb_address_reserved = 0;
2051 if (xp->family == AF_INET) { 1984
2052 sin = (struct sockaddr_in *) (addr + 1); 1985 pfkey_sockaddr_fill(&xp->selector.daddr, xp->selector.dport,
2053 sin->sin_family = AF_INET; 1986 (struct sockaddr *) (addr + 1),
2054 sin->sin_addr.s_addr = xp->selector.daddr.a4; 1987 xp->family);
2055 sin->sin_port = xp->selector.dport;
2056 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
2057 }
2058#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2059 else if (xp->family == AF_INET6) {
2060 sin6 = (struct sockaddr_in6 *) (addr + 1);
2061 sin6->sin6_family = AF_INET6;
2062 sin6->sin6_port = xp->selector.dport;
2063 sin6->sin6_flowinfo = 0;
2064 memcpy(&sin6->sin6_addr, xp->selector.daddr.a6,
2065 sizeof(struct in6_addr));
2066 sin6->sin6_scope_id = 0;
2067 }
2068#endif
2069 else
2070 BUG();
2071 1988
2072 /* hard time */ 1989 /* hard time */
2073 lifetime = (struct sadb_lifetime *) skb_put(skb, 1990 lifetime = (struct sadb_lifetime *) skb_put(skb,
@@ -2121,12 +2038,13 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2121 int mode; 2038 int mode;
2122 2039
2123 req_size = sizeof(struct sadb_x_ipsecrequest); 2040 req_size = sizeof(struct sadb_x_ipsecrequest);
2124 if (t->mode == XFRM_MODE_TUNNEL) 2041 if (t->mode == XFRM_MODE_TUNNEL) {
2125 req_size += ((t->encap_family == AF_INET ? 2042 socklen = pfkey_sockaddr_len(t->encap_family);
2126 sizeof(struct sockaddr_in) : 2043 req_size += socklen * 2;
2127 sizeof(struct sockaddr_in6)) * 2); 2044 } else {
2128 else
2129 size -= 2*socklen; 2045 size -= 2*socklen;
2046 socklen = 0;
2047 }
2130 rq = (void*)skb_put(skb, req_size); 2048 rq = (void*)skb_put(skb, req_size);
2131 pol->sadb_x_policy_len += req_size/8; 2049 pol->sadb_x_policy_len += req_size/8;
2132 memset(rq, 0, sizeof(*rq)); 2050 memset(rq, 0, sizeof(*rq));
@@ -2141,42 +2059,15 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
2141 if (t->optional) 2059 if (t->optional)
2142 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE; 2060 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
2143 rq->sadb_x_ipsecrequest_reqid = t->reqid; 2061 rq->sadb_x_ipsecrequest_reqid = t->reqid;
2062
2144 if (t->mode == XFRM_MODE_TUNNEL) { 2063 if (t->mode == XFRM_MODE_TUNNEL) {
2145 switch (t->encap_family) { 2064 u8 *sa = (void *)(rq + 1);
2146 case AF_INET: 2065 pfkey_sockaddr_fill(&t->saddr, 0,
2147 sin = (void*)(rq+1); 2066 (struct sockaddr *)sa,
2148 sin->sin_family = AF_INET; 2067 t->encap_family);
2149 sin->sin_addr.s_addr = t->saddr.a4; 2068 pfkey_sockaddr_fill(&t->id.daddr, 0,
2150 sin->sin_port = 0; 2069 (struct sockaddr *) (sa + socklen),
2151 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 2070 t->encap_family);
2152 sin++;
2153 sin->sin_family = AF_INET;
2154 sin->sin_addr.s_addr = t->id.daddr.a4;
2155 sin->sin_port = 0;
2156 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
2157 break;
2158#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2159 case AF_INET6:
2160 sin6 = (void*)(rq+1);
2161 sin6->sin6_family = AF_INET6;
2162 sin6->sin6_port = 0;
2163 sin6->sin6_flowinfo = 0;
2164 memcpy(&sin6->sin6_addr, t->saddr.a6,
2165 sizeof(struct in6_addr));
2166 sin6->sin6_scope_id = 0;
2167
2168 sin6++;
2169 sin6->sin6_family = AF_INET6;
2170 sin6->sin6_port = 0;
2171 sin6->sin6_flowinfo = 0;
2172 memcpy(&sin6->sin6_addr, t->id.daddr.a6,
2173 sizeof(struct in6_addr));
2174 sin6->sin6_scope_id = 0;
2175 break;
2176#endif
2177 default:
2178 break;
2179 }
2180 } 2071 }
2181 } 2072 }
2182 2073
@@ -2459,61 +2350,31 @@ out:
2459#ifdef CONFIG_NET_KEY_MIGRATE 2350#ifdef CONFIG_NET_KEY_MIGRATE
2460static int pfkey_sockaddr_pair_size(sa_family_t family) 2351static int pfkey_sockaddr_pair_size(sa_family_t family)
2461{ 2352{
2462 switch (family) { 2353 return PFKEY_ALIGN8(pfkey_sockaddr_len(family) * 2);
2463 case AF_INET:
2464 return PFKEY_ALIGN8(sizeof(struct sockaddr_in) * 2);
2465#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2466 case AF_INET6:
2467 return PFKEY_ALIGN8(sizeof(struct sockaddr_in6) * 2);
2468#endif
2469 default:
2470 return 0;
2471 }
2472 /* NOTREACHED */
2473} 2354}
2474 2355
2475static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq, 2356static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq,
2476 xfrm_address_t *saddr, xfrm_address_t *daddr, 2357 xfrm_address_t *saddr, xfrm_address_t *daddr,
2477 u16 *family) 2358 u16 *family)
2478{ 2359{
2479 struct sockaddr *sa = (struct sockaddr *)(rq + 1); 2360 u8 *sa = (u8 *) (rq + 1);
2361 int af, socklen;
2362
2480 if (rq->sadb_x_ipsecrequest_len < 2363 if (rq->sadb_x_ipsecrequest_len <
2481 pfkey_sockaddr_pair_size(sa->sa_family)) 2364 pfkey_sockaddr_pair_size(((struct sockaddr *)sa)->sa_family))
2482 return -EINVAL; 2365 return -EINVAL;
2483 2366
2484 switch (sa->sa_family) { 2367 af = pfkey_sockaddr_extract((struct sockaddr *) sa,
2485 case AF_INET: 2368 saddr);
2486 { 2369 if (!af)
2487 struct sockaddr_in *sin;
2488 sin = (struct sockaddr_in *)sa;
2489 if ((sin+1)->sin_family != AF_INET)
2490 return -EINVAL;
2491 memcpy(&saddr->a4, &sin->sin_addr, sizeof(saddr->a4));
2492 sin++;
2493 memcpy(&daddr->a4, &sin->sin_addr, sizeof(daddr->a4));
2494 *family = AF_INET;
2495 break;
2496 }
2497#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2498 case AF_INET6:
2499 {
2500 struct sockaddr_in6 *sin6;
2501 sin6 = (struct sockaddr_in6 *)sa;
2502 if ((sin6+1)->sin6_family != AF_INET6)
2503 return -EINVAL;
2504 memcpy(&saddr->a6, &sin6->sin6_addr,
2505 sizeof(saddr->a6));
2506 sin6++;
2507 memcpy(&daddr->a6, &sin6->sin6_addr,
2508 sizeof(daddr->a6));
2509 *family = AF_INET6;
2510 break;
2511 }
2512#endif
2513 default:
2514 return -EINVAL; 2370 return -EINVAL;
2515 }
2516 2371
2372 socklen = pfkey_sockaddr_len(af);
2373 if (pfkey_sockaddr_extract((struct sockaddr *) (sa + socklen),
2374 daddr) != af)
2375 return -EINVAL;
2376
2377 *family = af;
2517 return 0; 2378 return 0;
2518} 2379}
2519 2380
@@ -3091,10 +2952,6 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3091 struct sadb_msg *hdr; 2952 struct sadb_msg *hdr;
3092 struct sadb_address *addr; 2953 struct sadb_address *addr;
3093 struct sadb_x_policy *pol; 2954 struct sadb_x_policy *pol;
3094 struct sockaddr_in *sin;
3095#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3096 struct sockaddr_in6 *sin6;
3097#endif
3098 int sockaddr_size; 2955 int sockaddr_size;
3099 int size; 2956 int size;
3100 struct sadb_x_sec_ctx *sec_ctx; 2957 struct sadb_x_sec_ctx *sec_ctx;
@@ -3143,29 +3000,11 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3143 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 3000 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
3144 addr->sadb_address_proto = 0; 3001 addr->sadb_address_proto = 0;
3145 addr->sadb_address_reserved = 0; 3002 addr->sadb_address_reserved = 0;
3146 if (x->props.family == AF_INET) { 3003 addr->sadb_address_prefixlen =
3147 addr->sadb_address_prefixlen = 32; 3004 pfkey_sockaddr_fill(&x->props.saddr, 0,
3148 3005 (struct sockaddr *) (addr + 1),
3149 sin = (struct sockaddr_in *) (addr + 1); 3006 x->props.family);
3150 sin->sin_family = AF_INET; 3007 if (!addr->sadb_address_prefixlen)
3151 sin->sin_addr.s_addr = x->props.saddr.a4;
3152 sin->sin_port = 0;
3153 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3154 }
3155#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3156 else if (x->props.family == AF_INET6) {
3157 addr->sadb_address_prefixlen = 128;
3158
3159 sin6 = (struct sockaddr_in6 *) (addr + 1);
3160 sin6->sin6_family = AF_INET6;
3161 sin6->sin6_port = 0;
3162 sin6->sin6_flowinfo = 0;
3163 memcpy(&sin6->sin6_addr,
3164 x->props.saddr.a6, sizeof(struct in6_addr));
3165 sin6->sin6_scope_id = 0;
3166 }
3167#endif
3168 else
3169 BUG(); 3008 BUG();
3170 3009
3171 /* dst address */ 3010 /* dst address */
@@ -3177,29 +3016,11 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
3177 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 3016 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
3178 addr->sadb_address_proto = 0; 3017 addr->sadb_address_proto = 0;
3179 addr->sadb_address_reserved = 0; 3018 addr->sadb_address_reserved = 0;
3180 if (x->props.family == AF_INET) { 3019 addr->sadb_address_prefixlen =
3181 addr->sadb_address_prefixlen = 32; 3020 pfkey_sockaddr_fill(&x->id.daddr, 0,
3182 3021 (struct sockaddr *) (addr + 1),
3183 sin = (struct sockaddr_in *) (addr + 1); 3022 x->props.family);
3184 sin->sin_family = AF_INET; 3023 if (!addr->sadb_address_prefixlen)
3185 sin->sin_addr.s_addr = x->id.daddr.a4;
3186 sin->sin_port = 0;
3187 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3188 }
3189#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3190 else if (x->props.family == AF_INET6) {
3191 addr->sadb_address_prefixlen = 128;
3192
3193 sin6 = (struct sockaddr_in6 *) (addr + 1);
3194 sin6->sin6_family = AF_INET6;
3195 sin6->sin6_port = 0;
3196 sin6->sin6_flowinfo = 0;
3197 memcpy(&sin6->sin6_addr,
3198 x->id.daddr.a6, sizeof(struct in6_addr));
3199 sin6->sin6_scope_id = 0;
3200 }
3201#endif
3202 else
3203 BUG(); 3024 BUG();
3204 3025
3205 pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy)); 3026 pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy));
@@ -3325,10 +3146,6 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3325 struct sadb_sa *sa; 3146 struct sadb_sa *sa;
3326 struct sadb_address *addr; 3147 struct sadb_address *addr;
3327 struct sadb_x_nat_t_port *n_port; 3148 struct sadb_x_nat_t_port *n_port;
3328 struct sockaddr_in *sin;
3329#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3330 struct sockaddr_in6 *sin6;
3331#endif
3332 int sockaddr_size; 3149 int sockaddr_size;
3333 int size; 3150 int size;
3334 __u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0); 3151 __u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0);
@@ -3392,29 +3209,11 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3392 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 3209 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
3393 addr->sadb_address_proto = 0; 3210 addr->sadb_address_proto = 0;
3394 addr->sadb_address_reserved = 0; 3211 addr->sadb_address_reserved = 0;
3395 if (x->props.family == AF_INET) { 3212 addr->sadb_address_prefixlen =
3396 addr->sadb_address_prefixlen = 32; 3213 pfkey_sockaddr_fill(&x->props.saddr, 0,
3397 3214 (struct sockaddr *) (addr + 1),
3398 sin = (struct sockaddr_in *) (addr + 1); 3215 x->props.family);
3399 sin->sin_family = AF_INET; 3216 if (!addr->sadb_address_prefixlen)
3400 sin->sin_addr.s_addr = x->props.saddr.a4;
3401 sin->sin_port = 0;
3402 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3403 }
3404#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3405 else if (x->props.family == AF_INET6) {
3406 addr->sadb_address_prefixlen = 128;
3407
3408 sin6 = (struct sockaddr_in6 *) (addr + 1);
3409 sin6->sin6_family = AF_INET6;
3410 sin6->sin6_port = 0;
3411 sin6->sin6_flowinfo = 0;
3412 memcpy(&sin6->sin6_addr,
3413 x->props.saddr.a6, sizeof(struct in6_addr));
3414 sin6->sin6_scope_id = 0;
3415 }
3416#endif
3417 else
3418 BUG(); 3217 BUG();
3419 3218
3420 /* NAT_T_SPORT (old port) */ 3219 /* NAT_T_SPORT (old port) */
@@ -3433,28 +3232,11 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
3433 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 3232 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
3434 addr->sadb_address_proto = 0; 3233 addr->sadb_address_proto = 0;
3435 addr->sadb_address_reserved = 0; 3234 addr->sadb_address_reserved = 0;
3436 if (x->props.family == AF_INET) { 3235 addr->sadb_address_prefixlen =
3437 addr->sadb_address_prefixlen = 32; 3236 pfkey_sockaddr_fill(ipaddr, 0,
3438 3237 (struct sockaddr *) (addr + 1),
3439 sin = (struct sockaddr_in *) (addr + 1); 3238 x->props.family);
3440 sin->sin_family = AF_INET; 3239 if (!addr->sadb_address_prefixlen)
3441 sin->sin_addr.s_addr = ipaddr->a4;
3442 sin->sin_port = 0;
3443 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3444 }
3445#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3446 else if (x->props.family == AF_INET6) {
3447 addr->sadb_address_prefixlen = 128;
3448
3449 sin6 = (struct sockaddr_in6 *) (addr + 1);
3450 sin6->sin6_family = AF_INET6;
3451 sin6->sin6_port = 0;
3452 sin6->sin6_flowinfo = 0;
3453 memcpy(&sin6->sin6_addr, &ipaddr->a6, sizeof(struct in6_addr));
3454 sin6->sin6_scope_id = 0;
3455 }
3456#endif
3457 else
3458 BUG(); 3240 BUG();
3459 3241
3460 /* NAT_T_DPORT (new port) */ 3242 /* NAT_T_DPORT (new port) */
@@ -3472,10 +3254,6 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
3472 struct xfrm_selector *sel) 3254 struct xfrm_selector *sel)
3473{ 3255{
3474 struct sadb_address *addr; 3256 struct sadb_address *addr;
3475 struct sockaddr_in *sin;
3476#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3477 struct sockaddr_in6 *sin6;
3478#endif
3479 addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize); 3257 addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize);
3480 addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8; 3258 addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8;
3481 addr->sadb_address_exttype = type; 3259 addr->sadb_address_exttype = type;
@@ -3484,50 +3262,16 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
3484 3262
3485 switch (type) { 3263 switch (type) {
3486 case SADB_EXT_ADDRESS_SRC: 3264 case SADB_EXT_ADDRESS_SRC:
3487 if (sel->family == AF_INET) { 3265 addr->sadb_address_prefixlen = sel->prefixlen_s;
3488 addr->sadb_address_prefixlen = sel->prefixlen_s; 3266 pfkey_sockaddr_fill(&sel->saddr, 0,
3489 sin = (struct sockaddr_in *)(addr + 1); 3267 (struct sockaddr *)(addr + 1),
3490 sin->sin_family = AF_INET; 3268 sel->family);
3491 memcpy(&sin->sin_addr.s_addr, &sel->saddr,
3492 sizeof(sin->sin_addr.s_addr));
3493 sin->sin_port = 0;
3494 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3495 }
3496#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3497 else if (sel->family == AF_INET6) {
3498 addr->sadb_address_prefixlen = sel->prefixlen_s;
3499 sin6 = (struct sockaddr_in6 *)(addr + 1);
3500 sin6->sin6_family = AF_INET6;
3501 sin6->sin6_port = 0;
3502 sin6->sin6_flowinfo = 0;
3503 sin6->sin6_scope_id = 0;
3504 memcpy(&sin6->sin6_addr.s6_addr, &sel->saddr,
3505 sizeof(sin6->sin6_addr.s6_addr));
3506 }
3507#endif
3508 break; 3269 break;
3509 case SADB_EXT_ADDRESS_DST: 3270 case SADB_EXT_ADDRESS_DST:
3510 if (sel->family == AF_INET) { 3271 addr->sadb_address_prefixlen = sel->prefixlen_d;
3511 addr->sadb_address_prefixlen = sel->prefixlen_d; 3272 pfkey_sockaddr_fill(&sel->daddr, 0,
3512 sin = (struct sockaddr_in *)(addr + 1); 3273 (struct sockaddr *)(addr + 1),
3513 sin->sin_family = AF_INET; 3274 sel->family);
3514 memcpy(&sin->sin_addr.s_addr, &sel->daddr,
3515 sizeof(sin->sin_addr.s_addr));
3516 sin->sin_port = 0;
3517 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
3518 }
3519#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3520 else if (sel->family == AF_INET6) {
3521 addr->sadb_address_prefixlen = sel->prefixlen_d;
3522 sin6 = (struct sockaddr_in6 *)(addr + 1);
3523 sin6->sin6_family = AF_INET6;
3524 sin6->sin6_port = 0;
3525 sin6->sin6_flowinfo = 0;
3526 sin6->sin6_scope_id = 0;
3527 memcpy(&sin6->sin6_addr.s6_addr, &sel->daddr,
3528 sizeof(sin6->sin6_addr.s6_addr));
3529 }
3530#endif
3531 break; 3275 break;
3532 default: 3276 default:
3533 return -EINVAL; 3277 return -EINVAL;
@@ -3542,10 +3286,8 @@ static int set_ipsecrequest(struct sk_buff *skb,
3542 xfrm_address_t *src, xfrm_address_t *dst) 3286 xfrm_address_t *src, xfrm_address_t *dst)
3543{ 3287{
3544 struct sadb_x_ipsecrequest *rq; 3288 struct sadb_x_ipsecrequest *rq;
3545 struct sockaddr_in *sin; 3289 u8 *sa;
3546#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3290 int socklen = pfkey_sockaddr_len(family);
3547 struct sockaddr_in6 *sin6;
3548#endif
3549 int size_req; 3291 int size_req;
3550 3292
3551 size_req = sizeof(struct sadb_x_ipsecrequest) + 3293 size_req = sizeof(struct sadb_x_ipsecrequest) +
@@ -3559,38 +3301,10 @@ static int set_ipsecrequest(struct sk_buff *skb,
3559 rq->sadb_x_ipsecrequest_level = level; 3301 rq->sadb_x_ipsecrequest_level = level;
3560 rq->sadb_x_ipsecrequest_reqid = reqid; 3302 rq->sadb_x_ipsecrequest_reqid = reqid;
3561 3303
3562 switch (family) { 3304 sa = (u8 *) (rq + 1);
3563 case AF_INET: 3305 if (!pfkey_sockaddr_fill(src, 0, (struct sockaddr *)sa, family) ||
3564 sin = (struct sockaddr_in *)(rq + 1); 3306 !pfkey_sockaddr_fill(dst, 0, (struct sockaddr *)(sa + socklen), family))
3565 sin->sin_family = AF_INET;
3566 memcpy(&sin->sin_addr.s_addr, src,
3567 sizeof(sin->sin_addr.s_addr));
3568 sin++;
3569 sin->sin_family = AF_INET;
3570 memcpy(&sin->sin_addr.s_addr, dst,
3571 sizeof(sin->sin_addr.s_addr));
3572 break;
3573#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3574 case AF_INET6:
3575 sin6 = (struct sockaddr_in6 *)(rq + 1);
3576 sin6->sin6_family = AF_INET6;
3577 sin6->sin6_port = 0;
3578 sin6->sin6_flowinfo = 0;
3579 sin6->sin6_scope_id = 0;
3580 memcpy(&sin6->sin6_addr.s6_addr, src,
3581 sizeof(sin6->sin6_addr.s6_addr));
3582 sin6++;
3583 sin6->sin6_family = AF_INET6;
3584 sin6->sin6_port = 0;
3585 sin6->sin6_flowinfo = 0;
3586 sin6->sin6_scope_id = 0;
3587 memcpy(&sin6->sin6_addr.s6_addr, dst,
3588 sizeof(sin6->sin6_addr.s6_addr));
3589 break;
3590#endif
3591 default:
3592 return -EINVAL; 3307 return -EINVAL;
3593 }
3594 3308
3595 return 0; 3309 return 0;
3596} 3310}