Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'net-next-2.6-misc-20080612a' of git://git.linux-ipv6.org/gitroot/yoshfuji/linux-2.6-next

+451 -744
+2 -1
include/net/addrconf.h
··· 121 121 */ 122 122 extern int ipv6_addr_label_init(void); 123 123 extern void ipv6_addr_label_rtnl_register(void); 124 - extern u32 ipv6_addr_label(const struct in6_addr *addr, 124 + extern u32 ipv6_addr_label(struct net *net, 125 + const struct in6_addr *addr, 125 126 int type, int ifindex); 126 127 127 128 /*
-1
include/net/if_inet6.h
··· 148 148 #define IFA_HOST IPV6_ADDR_LOOPBACK 149 149 #define IFA_LINK IPV6_ADDR_LINKLOCAL 150 150 #define IFA_SITE IPV6_ADDR_SITELOCAL 151 - #define IFA_GLOBAL 0x0000U 152 151 153 152 struct ipv6_devstat { 154 153 struct proc_dir_entry *proc_dir_entry;
+19 -2
include/net/tcp.h
··· 399 399 struct tcp_options_received *opt_rx, 400 400 int estab); 401 401 402 + extern u8 *tcp_parse_md5sig_option(struct tcphdr *th); 403 + 402 404 /* 403 405 * TCP v4 functions exported for the inet6 API 404 406 */ ··· 1117 1115 #define TCP_MD5SIG_MAXKEYS (~(u32)0) /* really?! */ 1118 1116 1119 1117 /* - functions */ 1118 + extern int tcp_calc_md5_hash(char *md5_hash, 1119 + struct tcp_md5sig_key *key, 1120 + int bplen, 1121 + struct tcphdr *th, 1122 + unsigned int tcplen, 1123 + struct tcp_md5sig_pool *hp); 1124 + 1120 1125 extern int tcp_v4_calc_md5_hash(char *md5_hash, 1121 1126 struct tcp_md5sig_key *key, 1122 1127 struct sock *sk, 1123 1128 struct dst_entry *dst, 1124 1129 struct request_sock *req, 1125 1130 struct tcphdr *th, 1126 - int protocol, 1127 1131 unsigned int tcplen); 1128 1132 extern struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk, 1129 1133 struct sock *addr_sk); ··· 1141 1133 1142 1134 extern int tcp_v4_md5_do_del(struct sock *sk, 1143 1135 __be32 addr); 1136 + 1137 + #ifdef CONFIG_TCP_MD5SIG 1138 + #define tcp_twsk_md5_key(twsk) ((twsk)->tw_md5_keylen ? \ 1139 + &(struct tcp_md5sig_key) { \ 1140 + .key = (twsk)->tw_md5_key, \ 1141 + .keylen = (twsk)->tw_md5_keylen, \ 1142 + } : NULL) 1143 + #else 1144 + #define tcp_twsk_md5_key(twsk) NULL 1145 + #endif 1144 1146 1145 1147 extern struct tcp_md5sig_pool **tcp_alloc_md5sig_pool(void); 1146 1148 extern void tcp_free_md5sig_pool(void); ··· 1389 1371 struct dst_entry *dst, 1390 1372 struct request_sock *req, 1391 1373 struct tcphdr *th, 1392 - int protocol, 1393 1374 unsigned int len); 1394 1375 int (*md5_add) (struct sock *sk, 1395 1376 struct sock *addr_sk,
+70
net/ipv4/tcp.c
··· 2457 2457 static struct tcp_md5sig_pool **tcp_md5sig_pool; 2458 2458 static DEFINE_SPINLOCK(tcp_md5sig_pool_lock); 2459 2459 2460 + int 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 + } 2528 + EXPORT_SYMBOL(tcp_calc_md5_hash); 2529 + 2460 2530 static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool **pool) 2461 2531 { 2462 2532 int cpu;
+40
net/ipv4/tcp_input.c
··· 3448 3448 return 1; 3449 3449 } 3450 3450 3451 + #ifdef CONFIG_TCP_MD5SIG 3452 + /* 3453 + * Parse MD5 Signature option 3454 + */ 3455 + u8 *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 + 3451 3488 static inline void tcp_store_ts_recent(struct tcp_sock *tp) 3452 3489 { 3453 3490 tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; ··· 5502 5465 EXPORT_SYMBOL(sysctl_tcp_reordering); 5503 5466 EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); 5504 5467 EXPORT_SYMBOL(tcp_parse_options); 5468 + #ifdef CONFIG_TCP_MD5SIG 5469 + EXPORT_SYMBOL(tcp_parse_md5sig_option); 5470 + #endif 5505 5471 EXPORT_SYMBOL(tcp_rcv_established); 5506 5472 EXPORT_SYMBOL(tcp_rcv_state_process); 5507 5473 EXPORT_SYMBOL(tcp_initialize_rcv_mss);
+33 -131
net/ipv4/tcp_ipv4.c
··· 93 93 __be32 addr); 94 94 static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 95 95 __be32 saddr, __be32 daddr, 96 - struct tcphdr *th, int protocol, 97 - unsigned int tcplen); 96 + struct tcphdr *th, unsigned int tcplen); 97 + #else 98 + static inline 99 + struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr) 100 + { 101 + return NULL; 102 + } 98 103 #endif 99 104 100 105 struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { ··· 589 584 key, 590 585 ip_hdr(skb)->daddr, 591 586 ip_hdr(skb)->saddr, 592 - &rep.th, IPPROTO_TCP, 593 - arg.iov[0].iov_len); 587 + &rep.th, arg.iov[0].iov_len); 594 588 } 595 589 #endif 596 590 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, ··· 608 604 outside socket context is ugly, certainly. What can I do? 609 605 */ 610 606 611 - static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, 612 - struct sk_buff *skb, u32 seq, u32 ack, 613 - u32 win, u32 ts) 607 + static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, 608 + u32 win, u32 ts, int oif, 609 + struct tcp_md5sig_key *key) 614 610 { 615 611 struct tcphdr *th = tcp_hdr(skb); 616 612 struct { ··· 622 618 ]; 623 619 } rep; 624 620 struct ip_reply_arg arg; 625 - #ifdef CONFIG_TCP_MD5SIG 626 - struct tcp_md5sig_key *key; 627 - struct tcp_md5sig_key tw_key; 628 - #endif 629 621 630 622 memset(&rep.th, 0, sizeof(struct tcphdr)); 631 623 memset(&arg, 0, sizeof(arg)); ··· 647 647 rep.th.window = htons(win); 648 648 649 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 650 if (key) { 668 651 int offset = (ts) ? 3 : 0; 669 652 ··· 661 678 key, 662 679 ip_hdr(skb)->daddr, 663 680 ip_hdr(skb)->saddr, 664 - &rep.th, IPPROTO_TCP, 665 - arg.iov[0].iov_len); 681 + &rep.th, arg.iov[0].iov_len); 666 682 } 667 683 #endif 668 684 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, 669 685 ip_hdr(skb)->saddr, /* XXX */ 670 686 arg.iov[0].iov_len, IPPROTO_TCP, 0); 671 687 arg.csumoffset = offsetof(struct tcphdr, check) / 2; 672 - if (twsk) 673 - arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if; 688 + if (oif) 689 + arg.bound_dev_if = oif; 674 690 675 691 ip_send_reply(dev_net(skb->dev)->ipv4.tcp_sock, skb, 676 692 &arg, arg.iov[0].iov_len); ··· 682 700 struct inet_timewait_sock *tw = inet_twsk(sk); 683 701 struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 684 702 685 - tcp_v4_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 703 + tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 686 704 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 687 - tcptw->tw_ts_recent); 705 + tcptw->tw_ts_recent, 706 + tw->tw_bound_dev_if, 707 + tcp_twsk_md5_key(tcptw) 708 + ); 688 709 689 710 inet_twsk_put(tw); 690 711 } ··· 695 710 static void tcp_v4_reqsk_send_ack(struct sk_buff *skb, 696 711 struct request_sock *req) 697 712 { 698 - tcp_v4_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, 713 + tcp_v4_send_ack(skb, tcp_rsk(req)->snt_isn + 1, 699 714 tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, 700 - req->ts_recent); 715 + req->ts_recent, 716 + 0, 717 + tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr)); 701 718 } 702 719 703 720 /* ··· 991 1004 992 1005 static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 993 1006 __be32 saddr, __be32 daddr, 994 - struct tcphdr *th, int protocol, 1007 + struct tcphdr *th, 995 1008 unsigned int tcplen) 996 1009 { 997 - struct scatterlist sg[4]; 998 - __u16 data_len; 999 - int block = 0; 1000 - __sum16 old_checksum; 1001 1010 struct tcp_md5sig_pool *hp; 1002 1011 struct tcp4_pseudohdr *bp; 1003 - struct hash_desc *desc; 1004 1012 int err; 1005 - unsigned int nbytes = 0; 1006 1013 1007 1014 /* 1008 1015 * Okay, so RFC2385 is turned on for this connection, ··· 1008 1027 goto clear_hash_noput; 1009 1028 1010 1029 bp = &hp->md5_blk.ip4; 1011 - desc = &hp->md5_desc; 1012 1030 1013 1031 /* 1014 - * 1. the TCP pseudo-header (in the order: source IP address, 1032 + * The TCP pseudo-header (in the order: source IP address, 1015 1033 * destination IP address, zero-padded protocol number, and 1016 1034 * segment length) 1017 1035 */ 1018 1036 bp->saddr = saddr; 1019 1037 bp->daddr = daddr; 1020 1038 bp->pad = 0; 1021 - bp->protocol = protocol; 1039 + bp->protocol = IPPROTO_TCP; 1022 1040 bp->len = htons(tcplen); 1023 1041 1024 - sg_init_table(sg, 4); 1025 - 1026 - sg_set_buf(&sg[block++], bp, sizeof(*bp)); 1027 - nbytes += sizeof(*bp); 1028 - 1029 - /* 2. the TCP header, excluding options, and assuming a 1030 - * checksum of zero/ 1031 - */ 1032 - old_checksum = th->check; 1033 - th->check = 0; 1034 - sg_set_buf(&sg[block++], th, sizeof(struct tcphdr)); 1035 - nbytes += sizeof(struct tcphdr); 1036 - 1037 - /* 3. the TCP segment data (if any) */ 1038 - data_len = tcplen - (th->doff << 2); 1039 - if (data_len > 0) { 1040 - unsigned char *data = (unsigned char *)th + (th->doff << 2); 1041 - sg_set_buf(&sg[block++], data, data_len); 1042 - nbytes += data_len; 1043 - } 1044 - 1045 - /* 4. an independently-specified key or password, known to both 1046 - * TCPs and presumably connection-specific 1047 - */ 1048 - sg_set_buf(&sg[block++], key->key, key->keylen); 1049 - nbytes += key->keylen; 1050 - 1051 - sg_mark_end(&sg[block - 1]); 1052 - 1053 - /* Now store the Hash into the packet */ 1054 - err = crypto_hash_init(desc); 1055 - if (err) 1056 - goto clear_hash; 1057 - err = crypto_hash_update(desc, sg, nbytes); 1058 - if (err) 1059 - goto clear_hash; 1060 - err = crypto_hash_final(desc, md5_hash); 1042 + err = tcp_calc_md5_hash(md5_hash, key, sizeof(*bp), 1043 + th, tcplen, hp); 1061 1044 if (err) 1062 1045 goto clear_hash; 1063 1046 1064 - /* Reset header, and free up the crypto */ 1047 + /* Free up the crypto pool */ 1065 1048 tcp_put_md5sig_pool(); 1066 - th->check = old_checksum; 1067 - 1068 1049 out: 1069 1050 return 0; 1070 1051 clear_hash: ··· 1040 1097 struct sock *sk, 1041 1098 struct dst_entry *dst, 1042 1099 struct request_sock *req, 1043 - struct tcphdr *th, int protocol, 1100 + struct tcphdr *th, 1044 1101 unsigned int tcplen) 1045 1102 { 1046 1103 __be32 saddr, daddr; ··· 1056 1113 } 1057 1114 return tcp_v4_do_calc_md5_hash(md5_hash, key, 1058 1115 saddr, daddr, 1059 - th, protocol, tcplen); 1116 + th, tcplen); 1060 1117 } 1061 1118 1062 1119 EXPORT_SYMBOL(tcp_v4_calc_md5_hash); ··· 1075 1132 struct tcp_md5sig_key *hash_expected; 1076 1133 const struct iphdr *iph = ip_hdr(skb); 1077 1134 struct tcphdr *th = tcp_hdr(skb); 1078 - int length = (th->doff << 2) - sizeof(struct tcphdr); 1079 1135 int genhash; 1080 - unsigned char *ptr; 1081 1136 unsigned char newhash[16]; 1082 1137 1083 1138 hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr); 1139 + hash_location = tcp_parse_md5sig_option(th); 1084 1140 1085 - /* 1086 - * If the TCP option length is less than the TCP_MD5SIG 1087 - * option length, then we can shortcut 1088 - */ 1089 - if (length < TCPOLEN_MD5SIG) { 1090 - if (hash_expected) 1091 - return 1; 1092 - else 1093 - return 0; 1094 - } 1095 - 1096 - /* Okay, we can't shortcut - we have to grub through the options */ 1097 - ptr = (unsigned char *)(th + 1); 1098 - while (length > 0) { 1099 - int opcode = *ptr++; 1100 - int opsize; 1101 - 1102 - switch (opcode) { 1103 - case TCPOPT_EOL: 1104 - goto done_opts; 1105 - case TCPOPT_NOP: 1106 - length--; 1107 - continue; 1108 - default: 1109 - opsize = *ptr++; 1110 - if (opsize < 2) 1111 - goto done_opts; 1112 - if (opsize > length) 1113 - goto done_opts; 1114 - 1115 - if (opcode == TCPOPT_MD5SIG) { 1116 - hash_location = ptr; 1117 - goto done_opts; 1118 - } 1119 - } 1120 - ptr += opsize-2; 1121 - length -= opsize; 1122 - } 1123 - done_opts: 1124 1141 /* We've parsed the options - do we have a hash? */ 1125 1142 if (!hash_expected && !hash_location) 1126 1143 return 0; ··· 1107 1204 genhash = tcp_v4_do_calc_md5_hash(newhash, 1108 1205 hash_expected, 1109 1206 iph->saddr, iph->daddr, 1110 - th, sk->sk_protocol, 1111 - skb->len); 1207 + th, skb->len); 1112 1208 1113 1209 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 1114 1210 if (net_ratelimit()) {
+1 -2
net/ipv4/tcp_output.c
··· 605 605 md5, 606 606 sk, NULL, NULL, 607 607 tcp_hdr(skb), 608 - sk->sk_protocol, 609 608 skb->len); 610 609 } 611 610 #endif ··· 2263 2264 tp->af_specific->calc_md5_hash(md5_hash_location, 2264 2265 md5, 2265 2266 NULL, dst, req, 2266 - tcp_hdr(skb), sk->sk_protocol, 2267 + tcp_hdr(skb), 2267 2268 skb->len); 2268 2269 } 2269 2270 #endif
+15 -7
net/ipv6/addrconf.c
··· 229 229 return (dev->qdisc != &noop_qdisc); 230 230 } 231 231 232 + /* Check if a route is valid prefix route */ 233 + static inline int addrconf_is_prefix_route(const struct rt6_info *rt) 234 + { 235 + return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0); 236 + } 237 + 232 238 static void addrconf_del_timer(struct inet6_ifaddr *ifp) 233 239 { 234 240 if (del_timer(&ifp->timer)) ··· 781 775 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); 782 776 rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1); 783 777 784 - if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 778 + if (rt && addrconf_is_prefix_route(rt)) { 785 779 if (onlink == 0) { 786 780 ip6_del_rt(rt); 787 781 rt = NULL; ··· 962 956 return 0; 963 957 } 964 958 965 - static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score, 959 + static int ipv6_get_saddr_eval(struct net *net, 960 + struct ipv6_saddr_score *score, 966 961 struct ipv6_saddr_dst *dst, 967 962 int i) 968 963 { ··· 1042 1035 break; 1043 1036 case IPV6_SADDR_RULE_LABEL: 1044 1037 /* Rule 6: Prefer matching label */ 1045 - ret = ipv6_addr_label(&score->ifa->addr, score->addr_type, 1038 + ret = ipv6_addr_label(net, 1039 + &score->ifa->addr, score->addr_type, 1046 1040 score->ifa->idev->dev->ifindex) == dst->label; 1047 1041 break; 1048 1042 #ifdef CONFIG_IPV6_PRIVACY ··· 1097 1089 dst.addr = daddr; 1098 1090 dst.ifindex = dst_dev ? dst_dev->ifindex : 0; 1099 1091 dst.scope = __ipv6_addr_src_scope(dst_type); 1100 - dst.label = ipv6_addr_label(daddr, dst_type, dst.ifindex); 1092 + dst.label = ipv6_addr_label(net, daddr, dst_type, dst.ifindex); 1101 1093 dst.prefs = prefs; 1102 1094 1103 1095 hiscore->rule = -1; ··· 1165 1157 for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) { 1166 1158 int minihiscore, miniscore; 1167 1159 1168 - minihiscore = ipv6_get_saddr_eval(hiscore, &dst, i); 1169 - miniscore = ipv6_get_saddr_eval(score, &dst, i); 1160 + minihiscore = ipv6_get_saddr_eval(net, hiscore, &dst, i); 1161 + miniscore = ipv6_get_saddr_eval(net, score, &dst, i); 1170 1162 1171 1163 if (minihiscore > miniscore) { 1172 1164 if (i == IPV6_SADDR_RULE_SCOPE && ··· 1794 1786 rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, 1795 1787 dev->ifindex, 1); 1796 1788 1797 - if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 1789 + if (rt && addrconf_is_prefix_route(rt)) { 1798 1790 /* Autoconf prefix route */ 1799 1791 if (valid_lft == 0) { 1800 1792 ip6_del_rt(rt);
+75 -31
net/ipv6/addrlabel.c
··· 29 29 */ 30 30 struct ip6addrlbl_entry 31 31 { 32 + #ifdef CONFIG_NET_NS 33 + struct net *lbl_net; 34 + #endif 32 35 struct in6_addr prefix; 33 36 int prefixlen; 34 37 int ifindex; ··· 48 45 spinlock_t lock; 49 46 u32 seq; 50 47 } ip6addrlbl_table; 48 + 49 + static inline 50 + struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl) 51 + { 52 + #ifdef CONFIG_NET_NS 53 + return lbl->lbl_net; 54 + #else 55 + return &init_net; 56 + #endif 57 + } 51 58 52 59 /* 53 60 * Default policy table (RFC3484 + extensions) ··· 78 65 79 66 #define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL 80 67 81 - static const __initdata struct ip6addrlbl_init_table 68 + static const __net_initdata struct ip6addrlbl_init_table 82 69 { 83 70 const struct in6_addr *prefix; 84 71 int prefixlen; ··· 121 108 /* Object management */ 122 109 static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p) 123 110 { 111 + #ifdef CONFIG_NET_NS 112 + release_net(p->lbl_net); 113 + #endif 124 114 kfree(p); 125 115 } 126 116 ··· 144 128 } 145 129 146 130 /* Find label */ 147 - static int __ip6addrlbl_match(struct ip6addrlbl_entry *p, 131 + static int __ip6addrlbl_match(struct net *net, 132 + struct ip6addrlbl_entry *p, 148 133 const struct in6_addr *addr, 149 134 int addrtype, int ifindex) 150 135 { 136 + if (!net_eq(ip6addrlbl_net(p), net)) 137 + return 0; 151 138 if (p->ifindex && p->ifindex != ifindex) 152 139 return 0; 153 140 if (p->addrtype && p->addrtype != addrtype) ··· 160 141 return 1; 161 142 } 162 143 163 - static struct ip6addrlbl_entry *__ipv6_addr_label(const struct in6_addr *addr, 144 + static struct ip6addrlbl_entry *__ipv6_addr_label(struct net *net, 145 + const struct in6_addr *addr, 164 146 int type, int ifindex) 165 147 { 166 148 struct hlist_node *pos; 167 149 struct ip6addrlbl_entry *p; 168 150 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { 169 - if (__ip6addrlbl_match(p, addr, type, ifindex)) 151 + if (__ip6addrlbl_match(net, p, addr, type, ifindex)) 170 152 return p; 171 153 } 172 154 return NULL; 173 155 } 174 156 175 - u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex) 157 + u32 ipv6_addr_label(struct net *net, 158 + const struct in6_addr *addr, int type, int ifindex) 176 159 { 177 160 u32 label; 178 161 struct ip6addrlbl_entry *p; ··· 182 161 type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK; 183 162 184 163 rcu_read_lock(); 185 - p = __ipv6_addr_label(addr, type, ifindex); 164 + p = __ipv6_addr_label(net, addr, type, ifindex); 186 165 label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT; 187 166 rcu_read_unlock(); 188 167 ··· 195 174 } 196 175 197 176 /* allocate one entry */ 198 - static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix, 177 + static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net, 178 + const struct in6_addr *prefix, 199 179 int prefixlen, int ifindex, 200 180 u32 label) 201 181 { ··· 238 216 newp->addrtype = addrtype; 239 217 newp->label = label; 240 218 INIT_HLIST_NODE(&newp->list); 219 + #ifdef CONFIG_NET_NS 220 + newp->lbl_net = hold_net(net); 221 + #endif 241 222 atomic_set(&newp->refcnt, 1); 242 223 return newp; 243 224 } ··· 262 237 hlist_for_each_entry_safe(p, pos, n, 263 238 &ip6addrlbl_table.head, list) { 264 239 if (p->prefixlen == newp->prefixlen && 240 + net_eq(ip6addrlbl_net(p), ip6addrlbl_net(newp)) && 265 241 p->ifindex == newp->ifindex && 266 242 ipv6_addr_equal(&p->prefix, &newp->prefix)) { 267 243 if (!replace) { ··· 287 261 } 288 262 289 263 /* add a label */ 290 - static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen, 264 + static int ip6addrlbl_add(struct net *net, 265 + const struct in6_addr *prefix, int prefixlen, 291 266 int ifindex, u32 label, int replace) 292 267 { 293 268 struct ip6addrlbl_entry *newp; ··· 301 274 (unsigned int)label, 302 275 replace); 303 276 304 - newp = ip6addrlbl_alloc(prefix, prefixlen, ifindex, label); 277 + newp = ip6addrlbl_alloc(net, prefix, prefixlen, ifindex, label); 305 278 if (IS_ERR(newp)) 306 279 return PTR_ERR(newp); 307 280 spin_lock(&ip6addrlbl_table.lock); ··· 313 286 } 314 287 315 288 /* remove a label */ 316 - static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, 289 + static int __ip6addrlbl_del(struct net *net, 290 + const struct in6_addr *prefix, int prefixlen, 317 291 int ifindex) 318 292 { 319 293 struct ip6addrlbl_entry *p = NULL; ··· 328 300 329 301 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) { 330 302 if (p->prefixlen == prefixlen && 303 + net_eq(ip6addrlbl_net(p), net) && 331 304 p->ifindex == ifindex && 332 305 ipv6_addr_equal(&p->prefix, prefix)) { 333 306 hlist_del_rcu(&p->list); ··· 340 311 return ret; 341 312 } 342 313 343 - static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, 314 + static int ip6addrlbl_del(struct net *net, 315 + const struct in6_addr *prefix, int prefixlen, 344 316 int ifindex) 345 317 { 346 318 struct in6_addr prefix_buf; ··· 354 324 355 325 ipv6_addr_prefix(&prefix_buf, prefix, prefixlen); 356 326 spin_lock(&ip6addrlbl_table.lock); 357 - ret = __ip6addrlbl_del(&prefix_buf, prefixlen, ifindex); 327 + ret = __ip6addrlbl_del(net, &prefix_buf, prefixlen, ifindex); 358 328 spin_unlock(&ip6addrlbl_table.lock); 359 329 return ret; 360 330 } 361 331 362 332 /* add default label */ 363 - static __init int ip6addrlbl_init(void) 333 + static int __net_init ip6addrlbl_net_init(struct net *net) 364 334 { 365 335 int err = 0; 366 336 int i; ··· 368 338 ADDRLABEL(KERN_DEBUG "%s()\n", __func__); 369 339 370 340 for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) { 371 - int ret = ip6addrlbl_add(ip6addrlbl_init_table[i].prefix, 341 + int ret = ip6addrlbl_add(net, 342 + ip6addrlbl_init_table[i].prefix, 372 343 ip6addrlbl_init_table[i].prefixlen, 373 344 0, 374 345 ip6addrlbl_init_table[i].label, 0); ··· 380 349 return err; 381 350 } 382 351 352 + static void __net_exit ip6addrlbl_net_exit(struct net *net) 353 + { 354 + struct ip6addrlbl_entry *p = NULL; 355 + struct hlist_node *pos, *n; 356 + 357 + /* Remove all labels belonging to the exiting net */ 358 + spin_lock(&ip6addrlbl_table.lock); 359 + hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) { 360 + if (net_eq(ip6addrlbl_net(p), net)) { 361 + hlist_del_rcu(&p->list); 362 + ip6addrlbl_put(p); 363 + } 364 + } 365 + spin_unlock(&ip6addrlbl_table.lock); 366 + } 367 + 368 + static struct pernet_operations ipv6_addr_label_ops = { 369 + .init = ip6addrlbl_net_init, 370 + .exit = ip6addrlbl_net_exit, 371 + }; 372 + 383 373 int __init ipv6_addr_label_init(void) 384 374 { 385 375 spin_lock_init(&ip6addrlbl_table.lock); 386 376 387 - return ip6addrlbl_init(); 377 + return register_pernet_subsys(&ipv6_addr_label_ops); 388 378 } 389 379 390 380 static const struct nla_policy ifal_policy[IFAL_MAX+1] = { ··· 423 371 u32 label; 424 372 int err = 0; 425 373 426 - if (net != &init_net) 427 - return 0; 428 - 429 374 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 430 375 if (err < 0) 431 376 return err; ··· 434 385 return -EINVAL; 435 386 436 387 if (ifal->ifal_index && 437 - !__dev_get_by_index(&init_net, ifal->ifal_index)) 388 + !__dev_get_by_index(net, ifal->ifal_index)) 438 389 return -EINVAL; 439 390 440 391 if (!tb[IFAL_ADDRESS]) ··· 452 403 453 404 switch(nlh->nlmsg_type) { 454 405 case RTM_NEWADDRLABEL: 455 - err = ip6addrlbl_add(pfx, ifal->ifal_prefixlen, 406 + err = ip6addrlbl_add(net, pfx, ifal->ifal_prefixlen, 456 407 ifal->ifal_index, label, 457 408 nlh->nlmsg_flags & NLM_F_REPLACE); 458 409 break; 459 410 case RTM_DELADDRLABEL: 460 - err = ip6addrlbl_del(pfx, ifal->ifal_prefixlen, 411 + err = ip6addrlbl_del(net, pfx, ifal->ifal_prefixlen, 461 412 ifal->ifal_index); 462 413 break; 463 414 default: ··· 507 458 int idx = 0, s_idx = cb->args[0]; 508 459 int err; 509 460 510 - if (net != &init_net) 511 - return 0; 512 - 513 461 rcu_read_lock(); 514 462 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { 515 - if (idx >= s_idx) { 463 + if (idx >= s_idx && 464 + net_eq(ip6addrlbl_net(p), net)) { 516 465 if ((err = ip6addrlbl_fill(skb, p, 517 466 ip6addrlbl_table.seq, 518 467 NETLINK_CB(cb->skb).pid, ··· 546 499 struct ip6addrlbl_entry *p; 547 500 struct sk_buff *skb; 548 501 549 - if (net != &init_net) 550 - return 0; 551 - 552 502 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 553 503 if (err < 0) 554 504 return err; ··· 557 513 return -EINVAL; 558 514 559 515 if (ifal->ifal_index && 560 - !__dev_get_by_index(&init_net, ifal->ifal_index)) 516 + !__dev_get_by_index(net, ifal->ifal_index)) 561 517 return -EINVAL; 562 518 563 519 if (!tb[IFAL_ADDRESS]) ··· 568 524 return -EINVAL; 569 525 570 526 rcu_read_lock(); 571 - p = __ipv6_addr_label(addr, ipv6_addr_type(addr), ifal->ifal_index); 527 + p = __ipv6_addr_label(net, addr, ipv6_addr_type(addr), ifal->ifal_index); 572 528 if (p && ip6addrlbl_hold(p)) 573 529 p = NULL; 574 530 lseq = ip6addrlbl_table.seq; ··· 596 552 goto out; 597 553 } 598 554 599 - err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); 555 + err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); 600 556 out: 601 557 return err; 602 558 }
+1 -1
net/ipv6/ip6mr.c
··· 1240 1240 1241 1241 #endif 1242 1242 /* 1243 - * Spurious command, or MRT_VERSION which you cannot 1243 + * Spurious command, or MRT6_VERSION which you cannot 1244 1244 * set. 1245 1245 */ 1246 1246 default:
-1
net/ipv6/mcast.c
··· 162 162 ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \ 163 163 (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp)))) 164 164 165 - #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value) 166 165 #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) 167 166 168 167 #define IPV6_MLD_MAX_MSF 64
+25 -111
net/ipv6/tcp_ipv6.c
··· 80 80 #ifdef CONFIG_TCP_MD5SIG 81 81 static struct tcp_sock_af_ops tcp_sock_ipv6_specific; 82 82 static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; 83 + #else 84 + static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk, 85 + struct in6_addr *addr) 86 + { 87 + return NULL; 88 + } 83 89 #endif 84 90 85 91 static void tcp_v6_hash(struct sock *sk) ··· 740 734 static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 741 735 struct in6_addr *saddr, 742 736 struct in6_addr *daddr, 743 - struct tcphdr *th, int protocol, 744 - unsigned int tcplen) 737 + struct tcphdr *th, unsigned int tcplen) 745 738 { 746 - struct scatterlist sg[4]; 747 - __u16 data_len; 748 - int block = 0; 749 - __sum16 cksum; 750 739 struct tcp_md5sig_pool *hp; 751 740 struct tcp6_pseudohdr *bp; 752 - struct hash_desc *desc; 753 741 int err; 754 - unsigned int nbytes = 0; 755 742 756 743 hp = tcp_get_md5sig_pool(); 757 744 if (!hp) { 758 745 printk(KERN_WARNING "%s(): hash pool not found...\n", __func__); 759 746 goto clear_hash_noput; 760 747 } 748 + 761 749 bp = &hp->md5_blk.ip6; 762 - desc = &hp->md5_desc; 763 750 764 751 /* 1. TCP pseudo-header (RFC2460) */ 765 752 ipv6_addr_copy(&bp->saddr, saddr); 766 753 ipv6_addr_copy(&bp->daddr, daddr); 767 754 bp->len = htonl(tcplen); 768 - bp->protocol = htonl(protocol); 755 + bp->protocol = htonl(IPPROTO_TCP); 769 756 770 - sg_init_table(sg, 4); 757 + err = tcp_calc_md5_hash(md5_hash, key, sizeof(*bp), 758 + th, tcplen, hp); 771 759 772 - sg_set_buf(&sg[block++], bp, sizeof(*bp)); 773 - nbytes += sizeof(*bp); 774 - 775 - /* 2. TCP header, excluding options */ 776 - cksum = th->check; 777 - th->check = 0; 778 - sg_set_buf(&sg[block++], th, sizeof(*th)); 779 - nbytes += sizeof(*th); 780 - 781 - /* 3. TCP segment data (if any) */ 782 - data_len = tcplen - (th->doff << 2); 783 - if (data_len > 0) { 784 - u8 *data = (u8 *)th + (th->doff << 2); 785 - sg_set_buf(&sg[block++], data, data_len); 786 - nbytes += data_len; 787 - } 788 - 789 - /* 4. shared key */ 790 - sg_set_buf(&sg[block++], key->key, key->keylen); 791 - nbytes += key->keylen; 792 - 793 - sg_mark_end(&sg[block - 1]); 794 - 795 - /* Now store the hash into the packet */ 796 - err = crypto_hash_init(desc); 797 - if (err) { 798 - printk(KERN_WARNING "%s(): hash_init failed\n", __func__); 760 + if (err) 799 761 goto clear_hash; 800 - } 801 - err = crypto_hash_update(desc, sg, nbytes); 802 - if (err) { 803 - printk(KERN_WARNING "%s(): hash_update failed\n", __func__); 804 - goto clear_hash; 805 - } 806 - err = crypto_hash_final(desc, md5_hash); 807 - if (err) { 808 - printk(KERN_WARNING "%s(): hash_final failed\n", __func__); 809 - goto clear_hash; 810 - } 811 762 812 - /* Reset header, and free up the crypto */ 763 + /* Free up the crypto pool */ 813 764 tcp_put_md5sig_pool(); 814 - th->check = cksum; 815 765 out: 816 766 return 0; 817 767 clear_hash: ··· 781 819 struct sock *sk, 782 820 struct dst_entry *dst, 783 821 struct request_sock *req, 784 - struct tcphdr *th, int protocol, 785 - unsigned int tcplen) 822 + struct tcphdr *th, unsigned int tcplen) 786 823 { 787 824 struct in6_addr *saddr, *daddr; 788 825 ··· 794 833 } 795 834 return tcp_v6_do_calc_md5_hash(md5_hash, key, 796 835 saddr, daddr, 797 - th, protocol, tcplen); 836 + th, tcplen); 798 837 } 799 838 800 839 static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) ··· 803 842 struct tcp_md5sig_key *hash_expected; 804 843 struct ipv6hdr *ip6h = ipv6_hdr(skb); 805 844 struct tcphdr *th = tcp_hdr(skb); 806 - int length = (th->doff << 2) - sizeof (*th); 807 845 int genhash; 808 - u8 *ptr; 809 846 u8 newhash[16]; 810 847 811 848 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); 849 + hash_location = tcp_parse_md5sig_option(th); 812 850 813 - /* If the TCP option is too short, we can short cut */ 814 - if (length < TCPOLEN_MD5SIG) 815 - return hash_expected ? 1 : 0; 816 - 817 - /* parse options */ 818 - ptr = (u8*)(th + 1); 819 - while (length > 0) { 820 - int opcode = *ptr++; 821 - int opsize; 822 - 823 - switch(opcode) { 824 - case TCPOPT_EOL: 825 - goto done_opts; 826 - case TCPOPT_NOP: 827 - length--; 828 - continue; 829 - default: 830 - opsize = *ptr++; 831 - if (opsize < 2 || opsize > length) 832 - goto done_opts; 833 - if (opcode == TCPOPT_MD5SIG) { 834 - hash_location = ptr; 835 - goto done_opts; 836 - } 837 - } 838 - ptr += opsize - 2; 839 - length -= opsize; 840 - } 841 - 842 - done_opts: 843 851 /* do we have a hash as expected? */ 844 852 if (!hash_expected) { 845 853 if (!hash_location) ··· 838 908 genhash = tcp_v6_do_calc_md5_hash(newhash, 839 909 hash_expected, 840 910 &ip6h->saddr, &ip6h->daddr, 841 - th, sk->sk_protocol, 842 - skb->len); 911 + th, skb->len); 843 912 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 844 913 if (net_ratelimit()) { 845 914 printk(KERN_INFO "MD5 Hash %s for " ··· 978 1049 tcp_v6_do_calc_md5_hash((__u8 *)&opt[1], key, 979 1050 &ipv6_hdr(skb)->daddr, 980 1051 &ipv6_hdr(skb)->saddr, 981 - t1, IPPROTO_TCP, tot_len); 1052 + t1, tot_len); 982 1053 } 983 1054 #endif 984 1055 ··· 1015 1086 kfree_skb(buff); 1016 1087 } 1017 1088 1018 - static void tcp_v6_send_ack(struct tcp_timewait_sock *tw, 1019 - struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts) 1089 + static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts, 1090 + struct tcp_md5sig_key *key) 1020 1091 { 1021 1092 struct tcphdr *th = tcp_hdr(skb), *t1; 1022 1093 struct sk_buff *buff; ··· 1025 1096 struct sock *ctl_sk = net->ipv6.tcp_sk; 1026 1097 unsigned int tot_len = sizeof(struct tcphdr); 1027 1098 __be32 *topt; 1028 - #ifdef CONFIG_TCP_MD5SIG 1029 - struct tcp_md5sig_key *key; 1030 - struct tcp_md5sig_key tw_key; 1031 - #endif 1032 - 1033 - #ifdef CONFIG_TCP_MD5SIG 1034 - if (!tw && skb->sk) { 1035 - key = tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr); 1036 - } else if (tw && tw->tw_md5_keylen) { 1037 - tw_key.key = tw->tw_md5_key; 1038 - tw_key.keylen = tw->tw_md5_keylen; 1039 - key = &tw_key; 1040 - } else { 1041 - key = NULL; 1042 - } 1043 - #endif 1044 1099 1045 1100 if (ts) 1046 1101 tot_len += TCPOLEN_TSTAMP_ALIGNED; ··· 1068 1155 tcp_v6_do_calc_md5_hash((__u8 *)topt, key, 1069 1156 &ipv6_hdr(skb)->daddr, 1070 1157 &ipv6_hdr(skb)->saddr, 1071 - t1, IPPROTO_TCP, tot_len); 1158 + t1, tot_len); 1072 1159 } 1073 1160 #endif 1074 1161 ··· 1104 1191 struct inet_timewait_sock *tw = inet_twsk(sk); 1105 1192 struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 1106 1193 1107 - tcp_v6_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 1194 + tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 1108 1195 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 1109 - tcptw->tw_ts_recent); 1196 + tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw)); 1110 1197 1111 1198 inet_twsk_put(tw); 1112 1199 } 1113 1200 1114 1201 static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) 1115 1202 { 1116 - tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent); 1203 + tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent, 1204 + tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr)); 1117 1205 } 1118 1206 1119 1207
+170 -456
net/key/af_key.c
··· 579 579 return (proto ? proto : IPSEC_PROTO_ANY); 580 580 } 581 581 582 - static int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, 583 - xfrm_address_t *xaddr) 582 + static inline int pfkey_sockaddr_len(sa_family_t family) 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 + 595 + static 596 + int pfkey_sockaddr_extract(const struct sockaddr *sa, xfrm_address_t *xaddr) 597 + { 598 + switch (sa->sa_family) { 586 599 case AF_INET: 587 600 xaddr->a4 = 588 - ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr; 601 + ((struct sockaddr_in *)sa)->sin_addr.s_addr; 589 602 return AF_INET; 590 603 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 591 604 case AF_INET6: 592 605 memcpy(xaddr->a6, 593 - &((struct sockaddr_in6 *)(addr + 1))->sin6_addr, 606 + &((struct sockaddr_in6 *)sa)->sin6_addr, 594 607 sizeof(struct in6_addr)); 595 608 return AF_INET6; 596 609 #endif 597 - default: 598 - return 0; 599 610 } 600 - /* NOTREACHED */ 611 + return 0; 612 + } 613 + 614 + static 615 + int 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 603 621 static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs) ··· 660 642 } 661 643 662 644 #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) 645 + 663 646 static int 664 647 pfkey_sockaddr_size(sa_family_t family) 665 648 { 666 - switch (family) { 667 - case AF_INET: 668 - return PFKEY_ALIGN8(sizeof(struct sockaddr_in)); 669 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 670 - case AF_INET6: 671 - return PFKEY_ALIGN8(sizeof(struct sockaddr_in6)); 672 - #endif 673 - default: 674 - return 0; 675 - } 676 - /* NOTREACHED */ 649 + return PFKEY_ALIGN8(pfkey_sockaddr_len(family)); 677 650 } 678 651 679 652 static inline int pfkey_mode_from_xfrm(int mode) ··· 696 687 } 697 688 } 698 689 690 + static unsigned int pfkey_sockaddr_fill(xfrm_address_t *xaddr, __be16 port, 691 + struct sockaddr *sa, 692 + unsigned short family) 693 + { 694 + switch (family) { 695 + case AF_INET: 696 + { 697 + struct sockaddr_in *sin = (struct sockaddr_in *)sa; 698 + sin->sin_family = AF_INET; 699 + sin->sin_port = port; 700 + sin->sin_addr.s_addr = xaddr->a4; 701 + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 702 + return 32; 703 + } 704 + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 705 + case AF_INET6: 706 + { 707 + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; 708 + sin6->sin6_family = AF_INET6; 709 + sin6->sin6_port = port; 710 + sin6->sin6_flowinfo = 0; 711 + ipv6_addr_copy(&sin6->sin6_addr, (struct in6_addr *)xaddr->a6); 712 + sin6->sin6_scope_id = 0; 713 + return 128; 714 + } 715 + #endif 716 + } 717 + return 0; 718 + } 719 + 699 720 static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, 700 721 int add_keys, int hsc) 701 722 { ··· 736 697 struct sadb_address *addr; 737 698 struct sadb_key *key; 738 699 struct sadb_x_sa2 *sa2; 739 - struct sockaddr_in *sin; 740 700 struct sadb_x_sec_ctx *sec_ctx; 741 701 struct xfrm_sec_ctx *xfrm_ctx; 742 702 int ctx_size = 0; 743 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 744 - struct sockaddr_in6 *sin6; 745 - #endif 746 703 int size; 747 704 int auth_key_size = 0; 748 705 int encrypt_key_size = 0; ··· 767 732 } 768 733 769 734 /* identity & sensitivity */ 770 - 771 - if ((x->props.family == AF_INET && 772 - x->sel.saddr.a4 != x->props.saddr.a4) 773 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 774 - || (x->props.family == AF_INET6 && 775 - memcmp (x->sel.saddr.a6, x->props.saddr.a6, sizeof (struct in6_addr))) 776 - #endif 777 - ) 735 + if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr, x->props.family)) 778 736 size += sizeof(struct sadb_address) + sockaddr_size; 779 737 780 738 if (add_keys) { ··· 889 861 protocol's number." - RFC2367 */ 890 862 addr->sadb_address_proto = 0; 891 863 addr->sadb_address_reserved = 0; 892 - if (x->props.family == AF_INET) { 893 - addr->sadb_address_prefixlen = 32; 894 864 895 - sin = (struct sockaddr_in *) (addr + 1); 896 - sin->sin_family = AF_INET; 897 - sin->sin_addr.s_addr = x->props.saddr.a4; 898 - sin->sin_port = 0; 899 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 900 - } 901 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 902 - else if (x->props.family == AF_INET6) { 903 - addr->sadb_address_prefixlen = 128; 904 - 905 - sin6 = (struct sockaddr_in6 *) (addr + 1); 906 - sin6->sin6_family = AF_INET6; 907 - sin6->sin6_port = 0; 908 - sin6->sin6_flowinfo = 0; 909 - memcpy(&sin6->sin6_addr, x->props.saddr.a6, 910 - sizeof(struct in6_addr)); 911 - sin6->sin6_scope_id = 0; 912 - } 913 - #endif 914 - else 865 + addr->sadb_address_prefixlen = 866 + pfkey_sockaddr_fill(&x->props.saddr, 0, 867 + (struct sockaddr *) (addr + 1), 868 + x->props.family); 869 + if (!addr->sadb_address_prefixlen) 915 870 BUG(); 916 871 917 872 /* dst address */ ··· 905 894 sizeof(uint64_t); 906 895 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 907 896 addr->sadb_address_proto = 0; 908 - addr->sadb_address_prefixlen = 32; /* XXX */ 909 897 addr->sadb_address_reserved = 0; 910 - if (x->props.family == AF_INET) { 911 - sin = (struct sockaddr_in *) (addr + 1); 912 - sin->sin_family = AF_INET; 913 - sin->sin_addr.s_addr = x->id.daddr.a4; 914 - sin->sin_port = 0; 915 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 916 898 917 - if (x->sel.saddr.a4 != x->props.saddr.a4) { 918 - addr = (struct sadb_address*) skb_put(skb, 919 - sizeof(struct sadb_address)+sockaddr_size); 920 - addr->sadb_address_len = 921 - (sizeof(struct sadb_address)+sockaddr_size)/ 922 - sizeof(uint64_t); 923 - addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; 924 - addr->sadb_address_proto = 925 - pfkey_proto_from_xfrm(x->sel.proto); 926 - addr->sadb_address_prefixlen = x->sel.prefixlen_s; 927 - addr->sadb_address_reserved = 0; 928 - 929 - sin = (struct sockaddr_in *) (addr + 1); 930 - sin->sin_family = AF_INET; 931 - sin->sin_addr.s_addr = x->sel.saddr.a4; 932 - sin->sin_port = x->sel.sport; 933 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 934 - } 935 - } 936 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 937 - else if (x->props.family == AF_INET6) { 938 - addr->sadb_address_prefixlen = 128; 939 - 940 - sin6 = (struct sockaddr_in6 *) (addr + 1); 941 - sin6->sin6_family = AF_INET6; 942 - sin6->sin6_port = 0; 943 - sin6->sin6_flowinfo = 0; 944 - memcpy(&sin6->sin6_addr, x->id.daddr.a6, sizeof(struct in6_addr)); 945 - sin6->sin6_scope_id = 0; 946 - 947 - if (memcmp (x->sel.saddr.a6, x->props.saddr.a6, 948 - sizeof(struct in6_addr))) { 949 - addr = (struct sadb_address *) skb_put(skb, 950 - sizeof(struct sadb_address)+sockaddr_size); 951 - addr->sadb_address_len = 952 - (sizeof(struct sadb_address)+sockaddr_size)/ 953 - sizeof(uint64_t); 954 - addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; 955 - addr->sadb_address_proto = 956 - pfkey_proto_from_xfrm(x->sel.proto); 957 - addr->sadb_address_prefixlen = x->sel.prefixlen_s; 958 - addr->sadb_address_reserved = 0; 959 - 960 - sin6 = (struct sockaddr_in6 *) (addr + 1); 961 - sin6->sin6_family = AF_INET6; 962 - sin6->sin6_port = x->sel.sport; 963 - sin6->sin6_flowinfo = 0; 964 - memcpy(&sin6->sin6_addr, x->sel.saddr.a6, 965 - sizeof(struct in6_addr)); 966 - sin6->sin6_scope_id = 0; 967 - } 968 - } 969 - #endif 970 - else 899 + addr->sadb_address_prefixlen = 900 + pfkey_sockaddr_fill(&x->id.daddr, 0, 901 + (struct sockaddr *) (addr + 1), 902 + x->props.family); 903 + if (!addr->sadb_address_prefixlen) 971 904 BUG(); 905 + 906 + if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr, 907 + x->props.family)) { 908 + addr = (struct sadb_address*) skb_put(skb, 909 + sizeof(struct sadb_address)+sockaddr_size); 910 + addr->sadb_address_len = 911 + (sizeof(struct sadb_address)+sockaddr_size)/ 912 + sizeof(uint64_t); 913 + addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; 914 + addr->sadb_address_proto = 915 + pfkey_proto_from_xfrm(x->sel.proto); 916 + addr->sadb_address_prefixlen = x->sel.prefixlen_s; 917 + addr->sadb_address_reserved = 0; 918 + 919 + pfkey_sockaddr_fill(&x->sel.saddr, x->sel.sport, 920 + (struct sockaddr *) (addr + 1), 921 + x->props.family); 922 + } 972 923 973 924 /* auth key */ 974 925 if (add_keys && auth_key_size) { ··· 1826 1853 parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) 1827 1854 { 1828 1855 struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; 1829 - struct sockaddr_in *sin; 1830 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1831 - struct sockaddr_in6 *sin6; 1832 - #endif 1833 1856 int mode; 1834 1857 1835 1858 if (xp->xfrm_nr >= XFRM_MAX_DEPTH) ··· 1850 1881 1851 1882 /* addresses present only in tunnel mode */ 1852 1883 if (t->mode == XFRM_MODE_TUNNEL) { 1853 - struct sockaddr *sa; 1854 - sa = (struct sockaddr *)(rq+1); 1855 - switch(sa->sa_family) { 1856 - case AF_INET: 1857 - sin = (struct sockaddr_in*)sa; 1858 - t->saddr.a4 = sin->sin_addr.s_addr; 1859 - sin++; 1860 - if (sin->sin_family != AF_INET) 1861 - return -EINVAL; 1862 - t->id.daddr.a4 = sin->sin_addr.s_addr; 1863 - break; 1864 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1865 - case AF_INET6: 1866 - sin6 = (struct sockaddr_in6*)sa; 1867 - memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr)); 1868 - sin6++; 1869 - if (sin6->sin6_family != AF_INET6) 1870 - return -EINVAL; 1871 - memcpy(t->id.daddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr)); 1872 - break; 1873 - #endif 1874 - default: 1884 + u8 *sa = (u8 *) (rq + 1); 1885 + int family, socklen; 1886 + 1887 + family = pfkey_sockaddr_extract((struct sockaddr *)sa, 1888 + &t->saddr); 1889 + if (!family) 1875 1890 return -EINVAL; 1876 - } 1877 - t->encap_family = sa->sa_family; 1891 + 1892 + socklen = pfkey_sockaddr_len(family); 1893 + if (pfkey_sockaddr_extract((struct sockaddr *)(sa + socklen), 1894 + &t->id.daddr) != family) 1895 + return -EINVAL; 1896 + t->encap_family = family; 1878 1897 } else 1879 1898 t->encap_family = xp->family; 1880 1899 ··· 1909 1952 1910 1953 for (i=0; i<xp->xfrm_nr; i++) { 1911 1954 t = xp->xfrm_vec + i; 1912 - socklen += (t->encap_family == AF_INET ? 1913 - sizeof(struct sockaddr_in) : 1914 - sizeof(struct sockaddr_in6)); 1955 + socklen += pfkey_sockaddr_len(t->encap_family); 1915 1956 } 1916 1957 1917 1958 return sizeof(struct sadb_msg) + ··· 1942 1987 struct sadb_address *addr; 1943 1988 struct sadb_lifetime *lifetime; 1944 1989 struct sadb_x_policy *pol; 1945 - struct sockaddr_in *sin; 1946 1990 struct sadb_x_sec_ctx *sec_ctx; 1947 1991 struct xfrm_sec_ctx *xfrm_ctx; 1948 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1949 - struct sockaddr_in6 *sin6; 1950 - #endif 1951 1992 int i; 1952 1993 int size; 1953 1994 int sockaddr_size = pfkey_sockaddr_size(xp->family); 1954 - int socklen = (xp->family == AF_INET ? 1955 - sizeof(struct sockaddr_in) : 1956 - sizeof(struct sockaddr_in6)); 1995 + int socklen = pfkey_sockaddr_len(xp->family); 1957 1996 1958 1997 size = pfkey_xfrm_policy2msg_size(xp); 1959 1998 ··· 1965 2016 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); 1966 2017 addr->sadb_address_prefixlen = xp->selector.prefixlen_s; 1967 2018 addr->sadb_address_reserved = 0; 1968 - /* src address */ 1969 - if (xp->family == AF_INET) { 1970 - sin = (struct sockaddr_in *) (addr + 1); 1971 - sin->sin_family = AF_INET; 1972 - sin->sin_addr.s_addr = xp->selector.saddr.a4; 1973 - sin->sin_port = xp->selector.sport; 1974 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 1975 - } 1976 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1977 - else if (xp->family == AF_INET6) { 1978 - sin6 = (struct sockaddr_in6 *) (addr + 1); 1979 - sin6->sin6_family = AF_INET6; 1980 - sin6->sin6_port = xp->selector.sport; 1981 - sin6->sin6_flowinfo = 0; 1982 - memcpy(&sin6->sin6_addr, xp->selector.saddr.a6, 1983 - sizeof(struct in6_addr)); 1984 - sin6->sin6_scope_id = 0; 1985 - } 1986 - #endif 1987 - else 2019 + if (!pfkey_sockaddr_fill(&xp->selector.saddr, 2020 + xp->selector.sport, 2021 + (struct sockaddr *) (addr + 1), 2022 + xp->family)) 1988 2023 BUG(); 1989 2024 1990 2025 /* dst address */ ··· 1981 2048 addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); 1982 2049 addr->sadb_address_prefixlen = xp->selector.prefixlen_d; 1983 2050 addr->sadb_address_reserved = 0; 1984 - if (xp->family == AF_INET) { 1985 - sin = (struct sockaddr_in *) (addr + 1); 1986 - sin->sin_family = AF_INET; 1987 - sin->sin_addr.s_addr = xp->selector.daddr.a4; 1988 - sin->sin_port = xp->selector.dport; 1989 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 1990 - } 1991 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1992 - else if (xp->family == AF_INET6) { 1993 - sin6 = (struct sockaddr_in6 *) (addr + 1); 1994 - sin6->sin6_family = AF_INET6; 1995 - sin6->sin6_port = xp->selector.dport; 1996 - sin6->sin6_flowinfo = 0; 1997 - memcpy(&sin6->sin6_addr, xp->selector.daddr.a6, 1998 - sizeof(struct in6_addr)); 1999 - sin6->sin6_scope_id = 0; 2000 - } 2001 - #endif 2002 - else 2003 - BUG(); 2051 + 2052 + pfkey_sockaddr_fill(&xp->selector.daddr, xp->selector.dport, 2053 + (struct sockaddr *) (addr + 1), 2054 + xp->family); 2004 2055 2005 2056 /* hard time */ 2006 2057 lifetime = (struct sadb_lifetime *) skb_put(skb, ··· 2038 2121 int mode; 2039 2122 2040 2123 req_size = sizeof(struct sadb_x_ipsecrequest); 2041 - if (t->mode == XFRM_MODE_TUNNEL) 2042 - req_size += ((t->encap_family == AF_INET ? 2043 - sizeof(struct sockaddr_in) : 2044 - sizeof(struct sockaddr_in6)) * 2); 2045 - else 2124 + if (t->mode == XFRM_MODE_TUNNEL) { 2125 + socklen = pfkey_sockaddr_len(t->encap_family); 2126 + req_size += socklen * 2; 2127 + } else { 2046 2128 size -= 2*socklen; 2129 + socklen = 0; 2130 + } 2047 2131 rq = (void*)skb_put(skb, req_size); 2048 2132 pol->sadb_x_policy_len += req_size/8; 2049 2133 memset(rq, 0, sizeof(*rq)); ··· 2059 2141 if (t->optional) 2060 2142 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE; 2061 2143 rq->sadb_x_ipsecrequest_reqid = t->reqid; 2062 - if (t->mode == XFRM_MODE_TUNNEL) { 2063 - switch (t->encap_family) { 2064 - case AF_INET: 2065 - sin = (void*)(rq+1); 2066 - sin->sin_family = AF_INET; 2067 - sin->sin_addr.s_addr = t->saddr.a4; 2068 - sin->sin_port = 0; 2069 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 2070 - sin++; 2071 - sin->sin_family = AF_INET; 2072 - sin->sin_addr.s_addr = t->id.daddr.a4; 2073 - sin->sin_port = 0; 2074 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 2075 - break; 2076 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 2077 - case AF_INET6: 2078 - sin6 = (void*)(rq+1); 2079 - sin6->sin6_family = AF_INET6; 2080 - sin6->sin6_port = 0; 2081 - sin6->sin6_flowinfo = 0; 2082 - memcpy(&sin6->sin6_addr, t->saddr.a6, 2083 - sizeof(struct in6_addr)); 2084 - sin6->sin6_scope_id = 0; 2085 2144 2086 - sin6++; 2087 - sin6->sin6_family = AF_INET6; 2088 - sin6->sin6_port = 0; 2089 - sin6->sin6_flowinfo = 0; 2090 - memcpy(&sin6->sin6_addr, t->id.daddr.a6, 2091 - sizeof(struct in6_addr)); 2092 - sin6->sin6_scope_id = 0; 2093 - break; 2094 - #endif 2095 - default: 2096 - break; 2097 - } 2145 + if (t->mode == XFRM_MODE_TUNNEL) { 2146 + u8 *sa = (void *)(rq + 1); 2147 + pfkey_sockaddr_fill(&t->saddr, 0, 2148 + (struct sockaddr *)sa, 2149 + t->encap_family); 2150 + pfkey_sockaddr_fill(&t->id.daddr, 0, 2151 + (struct sockaddr *) (sa + socklen), 2152 + t->encap_family); 2098 2153 } 2099 2154 } 2100 2155 ··· 2350 2459 #ifdef CONFIG_NET_KEY_MIGRATE 2351 2460 static int pfkey_sockaddr_pair_size(sa_family_t family) 2352 2461 { 2353 - switch (family) { 2354 - case AF_INET: 2355 - return PFKEY_ALIGN8(sizeof(struct sockaddr_in) * 2); 2356 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 2357 - case AF_INET6: 2358 - return PFKEY_ALIGN8(sizeof(struct sockaddr_in6) * 2); 2359 - #endif 2360 - default: 2361 - return 0; 2362 - } 2363 - /* NOTREACHED */ 2462 + return PFKEY_ALIGN8(pfkey_sockaddr_len(family) * 2); 2364 2463 } 2365 2464 2366 2465 static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq, 2367 2466 xfrm_address_t *saddr, xfrm_address_t *daddr, 2368 2467 u16 *family) 2369 2468 { 2370 - struct sockaddr *sa = (struct sockaddr *)(rq + 1); 2469 + u8 *sa = (u8 *) (rq + 1); 2470 + int af, socklen; 2471 + 2371 2472 if (rq->sadb_x_ipsecrequest_len < 2372 - pfkey_sockaddr_pair_size(sa->sa_family)) 2473 + pfkey_sockaddr_pair_size(((struct sockaddr *)sa)->sa_family)) 2373 2474 return -EINVAL; 2374 2475 2375 - switch (sa->sa_family) { 2376 - case AF_INET: 2377 - { 2378 - struct sockaddr_in *sin; 2379 - sin = (struct sockaddr_in *)sa; 2380 - if ((sin+1)->sin_family != AF_INET) 2381 - return -EINVAL; 2382 - memcpy(&saddr->a4, &sin->sin_addr, sizeof(saddr->a4)); 2383 - sin++; 2384 - memcpy(&daddr->a4, &sin->sin_addr, sizeof(daddr->a4)); 2385 - *family = AF_INET; 2386 - break; 2387 - } 2388 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 2389 - case AF_INET6: 2390 - { 2391 - struct sockaddr_in6 *sin6; 2392 - sin6 = (struct sockaddr_in6 *)sa; 2393 - if ((sin6+1)->sin6_family != AF_INET6) 2394 - return -EINVAL; 2395 - memcpy(&saddr->a6, &sin6->sin6_addr, 2396 - sizeof(saddr->a6)); 2397 - sin6++; 2398 - memcpy(&daddr->a6, &sin6->sin6_addr, 2399 - sizeof(daddr->a6)); 2400 - *family = AF_INET6; 2401 - break; 2402 - } 2403 - #endif 2404 - default: 2476 + af = pfkey_sockaddr_extract((struct sockaddr *) sa, 2477 + saddr); 2478 + if (!af) 2405 2479 return -EINVAL; 2406 - } 2407 2480 2481 + socklen = pfkey_sockaddr_len(af); 2482 + if (pfkey_sockaddr_extract((struct sockaddr *) (sa + socklen), 2483 + daddr) != af) 2484 + return -EINVAL; 2485 + 2486 + *family = af; 2408 2487 return 0; 2409 2488 } 2410 2489 ··· 2952 3091 struct sadb_msg *hdr; 2953 3092 struct sadb_address *addr; 2954 3093 struct sadb_x_policy *pol; 2955 - struct sockaddr_in *sin; 2956 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 2957 - struct sockaddr_in6 *sin6; 2958 - #endif 2959 3094 int sockaddr_size; 2960 3095 int size; 2961 3096 struct sadb_x_sec_ctx *sec_ctx; ··· 3000 3143 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 3001 3144 addr->sadb_address_proto = 0; 3002 3145 addr->sadb_address_reserved = 0; 3003 - if (x->props.family == AF_INET) { 3004 - addr->sadb_address_prefixlen = 32; 3005 - 3006 - sin = (struct sockaddr_in *) (addr + 1); 3007 - sin->sin_family = AF_INET; 3008 - sin->sin_addr.s_addr = x->props.saddr.a4; 3009 - sin->sin_port = 0; 3010 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 3011 - } 3012 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3013 - else if (x->props.family == AF_INET6) { 3014 - addr->sadb_address_prefixlen = 128; 3015 - 3016 - sin6 = (struct sockaddr_in6 *) (addr + 1); 3017 - sin6->sin6_family = AF_INET6; 3018 - sin6->sin6_port = 0; 3019 - sin6->sin6_flowinfo = 0; 3020 - memcpy(&sin6->sin6_addr, 3021 - x->props.saddr.a6, sizeof(struct in6_addr)); 3022 - sin6->sin6_scope_id = 0; 3023 - } 3024 - #endif 3025 - else 3146 + addr->sadb_address_prefixlen = 3147 + pfkey_sockaddr_fill(&x->props.saddr, 0, 3148 + (struct sockaddr *) (addr + 1), 3149 + x->props.family); 3150 + if (!addr->sadb_address_prefixlen) 3026 3151 BUG(); 3027 3152 3028 3153 /* dst address */ ··· 3016 3177 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 3017 3178 addr->sadb_address_proto = 0; 3018 3179 addr->sadb_address_reserved = 0; 3019 - if (x->props.family == AF_INET) { 3020 - addr->sadb_address_prefixlen = 32; 3021 - 3022 - sin = (struct sockaddr_in *) (addr + 1); 3023 - sin->sin_family = AF_INET; 3024 - sin->sin_addr.s_addr = x->id.daddr.a4; 3025 - sin->sin_port = 0; 3026 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 3027 - } 3028 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3029 - else if (x->props.family == AF_INET6) { 3030 - addr->sadb_address_prefixlen = 128; 3031 - 3032 - sin6 = (struct sockaddr_in6 *) (addr + 1); 3033 - sin6->sin6_family = AF_INET6; 3034 - sin6->sin6_port = 0; 3035 - sin6->sin6_flowinfo = 0; 3036 - memcpy(&sin6->sin6_addr, 3037 - x->id.daddr.a6, sizeof(struct in6_addr)); 3038 - sin6->sin6_scope_id = 0; 3039 - } 3040 - #endif 3041 - else 3180 + addr->sadb_address_prefixlen = 3181 + pfkey_sockaddr_fill(&x->id.daddr, 0, 3182 + (struct sockaddr *) (addr + 1), 3183 + x->props.family); 3184 + if (!addr->sadb_address_prefixlen) 3042 3185 BUG(); 3043 3186 3044 3187 pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy)); ··· 3146 3325 struct sadb_sa *sa; 3147 3326 struct sadb_address *addr; 3148 3327 struct sadb_x_nat_t_port *n_port; 3149 - struct sockaddr_in *sin; 3150 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3151 - struct sockaddr_in6 *sin6; 3152 - #endif 3153 3328 int sockaddr_size; 3154 3329 int size; 3155 3330 __u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0); ··· 3209 3392 addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 3210 3393 addr->sadb_address_proto = 0; 3211 3394 addr->sadb_address_reserved = 0; 3212 - if (x->props.family == AF_INET) { 3213 - addr->sadb_address_prefixlen = 32; 3214 - 3215 - sin = (struct sockaddr_in *) (addr + 1); 3216 - sin->sin_family = AF_INET; 3217 - sin->sin_addr.s_addr = x->props.saddr.a4; 3218 - sin->sin_port = 0; 3219 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 3220 - } 3221 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3222 - else if (x->props.family == AF_INET6) { 3223 - addr->sadb_address_prefixlen = 128; 3224 - 3225 - sin6 = (struct sockaddr_in6 *) (addr + 1); 3226 - sin6->sin6_family = AF_INET6; 3227 - sin6->sin6_port = 0; 3228 - sin6->sin6_flowinfo = 0; 3229 - memcpy(&sin6->sin6_addr, 3230 - x->props.saddr.a6, sizeof(struct in6_addr)); 3231 - sin6->sin6_scope_id = 0; 3232 - } 3233 - #endif 3234 - else 3395 + addr->sadb_address_prefixlen = 3396 + pfkey_sockaddr_fill(&x->props.saddr, 0, 3397 + (struct sockaddr *) (addr + 1), 3398 + x->props.family); 3399 + if (!addr->sadb_address_prefixlen) 3235 3400 BUG(); 3236 3401 3237 3402 /* NAT_T_SPORT (old port) */ ··· 3232 3433 addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; 3233 3434 addr->sadb_address_proto = 0; 3234 3435 addr->sadb_address_reserved = 0; 3235 - if (x->props.family == AF_INET) { 3236 - addr->sadb_address_prefixlen = 32; 3237 - 3238 - sin = (struct sockaddr_in *) (addr + 1); 3239 - sin->sin_family = AF_INET; 3240 - sin->sin_addr.s_addr = ipaddr->a4; 3241 - sin->sin_port = 0; 3242 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 3243 - } 3244 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3245 - else if (x->props.family == AF_INET6) { 3246 - addr->sadb_address_prefixlen = 128; 3247 - 3248 - sin6 = (struct sockaddr_in6 *) (addr + 1); 3249 - sin6->sin6_family = AF_INET6; 3250 - sin6->sin6_port = 0; 3251 - sin6->sin6_flowinfo = 0; 3252 - memcpy(&sin6->sin6_addr, &ipaddr->a6, sizeof(struct in6_addr)); 3253 - sin6->sin6_scope_id = 0; 3254 - } 3255 - #endif 3256 - else 3436 + addr->sadb_address_prefixlen = 3437 + pfkey_sockaddr_fill(ipaddr, 0, 3438 + (struct sockaddr *) (addr + 1), 3439 + x->props.family); 3440 + if (!addr->sadb_address_prefixlen) 3257 3441 BUG(); 3258 3442 3259 3443 /* NAT_T_DPORT (new port) */ ··· 3254 3472 struct xfrm_selector *sel) 3255 3473 { 3256 3474 struct sadb_address *addr; 3257 - struct sockaddr_in *sin; 3258 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3259 - struct sockaddr_in6 *sin6; 3260 - #endif 3261 3475 addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize); 3262 3476 addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8; 3263 3477 addr->sadb_address_exttype = type; ··· 3262 3484 3263 3485 switch (type) { 3264 3486 case SADB_EXT_ADDRESS_SRC: 3265 - if (sel->family == AF_INET) { 3266 - addr->sadb_address_prefixlen = sel->prefixlen_s; 3267 - sin = (struct sockaddr_in *)(addr + 1); 3268 - sin->sin_family = AF_INET; 3269 - memcpy(&sin->sin_addr.s_addr, &sel->saddr, 3270 - sizeof(sin->sin_addr.s_addr)); 3271 - sin->sin_port = 0; 3272 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 3273 - } 3274 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3275 - else if (sel->family == AF_INET6) { 3276 - addr->sadb_address_prefixlen = sel->prefixlen_s; 3277 - sin6 = (struct sockaddr_in6 *)(addr + 1); 3278 - sin6->sin6_family = AF_INET6; 3279 - sin6->sin6_port = 0; 3280 - sin6->sin6_flowinfo = 0; 3281 - sin6->sin6_scope_id = 0; 3282 - memcpy(&sin6->sin6_addr.s6_addr, &sel->saddr, 3283 - sizeof(sin6->sin6_addr.s6_addr)); 3284 - } 3285 - #endif 3487 + addr->sadb_address_prefixlen = sel->prefixlen_s; 3488 + pfkey_sockaddr_fill(&sel->saddr, 0, 3489 + (struct sockaddr *)(addr + 1), 3490 + sel->family); 3286 3491 break; 3287 3492 case SADB_EXT_ADDRESS_DST: 3288 - if (sel->family == AF_INET) { 3289 - addr->sadb_address_prefixlen = sel->prefixlen_d; 3290 - sin = (struct sockaddr_in *)(addr + 1); 3291 - sin->sin_family = AF_INET; 3292 - memcpy(&sin->sin_addr.s_addr, &sel->daddr, 3293 - sizeof(sin->sin_addr.s_addr)); 3294 - sin->sin_port = 0; 3295 - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 3296 - } 3297 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3298 - else if (sel->family == AF_INET6) { 3299 - addr->sadb_address_prefixlen = sel->prefixlen_d; 3300 - sin6 = (struct sockaddr_in6 *)(addr + 1); 3301 - sin6->sin6_family = AF_INET6; 3302 - sin6->sin6_port = 0; 3303 - sin6->sin6_flowinfo = 0; 3304 - sin6->sin6_scope_id = 0; 3305 - memcpy(&sin6->sin6_addr.s6_addr, &sel->daddr, 3306 - sizeof(sin6->sin6_addr.s6_addr)); 3307 - } 3308 - #endif 3493 + addr->sadb_address_prefixlen = sel->prefixlen_d; 3494 + pfkey_sockaddr_fill(&sel->daddr, 0, 3495 + (struct sockaddr *)(addr + 1), 3496 + sel->family); 3309 3497 break; 3310 3498 default: 3311 3499 return -EINVAL; ··· 3286 3542 xfrm_address_t *src, xfrm_address_t *dst) 3287 3543 { 3288 3544 struct sadb_x_ipsecrequest *rq; 3289 - struct sockaddr_in *sin; 3290 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3291 - struct sockaddr_in6 *sin6; 3292 - #endif 3545 + u8 *sa; 3546 + int socklen = pfkey_sockaddr_len(family); 3293 3547 int size_req; 3294 3548 3295 3549 size_req = sizeof(struct sadb_x_ipsecrequest) + ··· 3301 3559 rq->sadb_x_ipsecrequest_level = level; 3302 3560 rq->sadb_x_ipsecrequest_reqid = reqid; 3303 3561 3304 - switch (family) { 3305 - case AF_INET: 3306 - sin = (struct sockaddr_in *)(rq + 1); 3307 - sin->sin_family = AF_INET; 3308 - memcpy(&sin->sin_addr.s_addr, src, 3309 - sizeof(sin->sin_addr.s_addr)); 3310 - sin++; 3311 - sin->sin_family = AF_INET; 3312 - memcpy(&sin->sin_addr.s_addr, dst, 3313 - sizeof(sin->sin_addr.s_addr)); 3314 - break; 3315 - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3316 - case AF_INET6: 3317 - sin6 = (struct sockaddr_in6 *)(rq + 1); 3318 - sin6->sin6_family = AF_INET6; 3319 - sin6->sin6_port = 0; 3320 - sin6->sin6_flowinfo = 0; 3321 - sin6->sin6_scope_id = 0; 3322 - memcpy(&sin6->sin6_addr.s6_addr, src, 3323 - sizeof(sin6->sin6_addr.s6_addr)); 3324 - sin6++; 3325 - sin6->sin6_family = AF_INET6; 3326 - sin6->sin6_port = 0; 3327 - sin6->sin6_flowinfo = 0; 3328 - sin6->sin6_scope_id = 0; 3329 - memcpy(&sin6->sin6_addr.s6_addr, dst, 3330 - sizeof(sin6->sin6_addr.s6_addr)); 3331 - break; 3332 - #endif 3333 - default: 3562 + sa = (u8 *) (rq + 1); 3563 + if (!pfkey_sockaddr_fill(src, 0, (struct sockaddr *)sa, family) || 3564 + !pfkey_sockaddr_fill(dst, 0, (struct sockaddr *)(sa + socklen), family)) 3334 3565 return -EINVAL; 3335 - } 3336 3566 3337 3567 return 0; 3338 3568 }