tcp_ipv6.c (45f6fad84cc305103b28d73482b344d7f5b76f39) | tcp_ipv6.c (7450aaf61f0ae2ee6cc6491138d11df2c25e7609) |
---|---|
1/* 2 * TCP over IPv6 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * Based on: --- 106 unchanged lines hidden (view full) --- 115 int addr_len) 116{ 117 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; 118 struct inet_sock *inet = inet_sk(sk); 119 struct inet_connection_sock *icsk = inet_csk(sk); 120 struct ipv6_pinfo *np = inet6_sk(sk); 121 struct tcp_sock *tp = tcp_sk(sk); 122 struct in6_addr *saddr = NULL, *final_p, final; | 1/* 2 * TCP over IPv6 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * Based on: --- 106 unchanged lines hidden (view full) --- 115 int addr_len) 116{ 117 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; 118 struct inet_sock *inet = inet_sk(sk); 119 struct inet_connection_sock *icsk = inet_csk(sk); 120 struct ipv6_pinfo *np = inet6_sk(sk); 121 struct tcp_sock *tp = tcp_sk(sk); 122 struct in6_addr *saddr = NULL, *final_p, final; |
123 struct ipv6_txoptions *opt; | |
124 struct flowi6 fl6; 125 struct dst_entry *dst; 126 int addr_type; 127 int err; 128 129 if (addr_len < SIN6_LEN_RFC2133) 130 return -EINVAL; 131 --- 99 unchanged lines hidden (view full) --- 231 fl6.flowi6_proto = IPPROTO_TCP; 232 fl6.daddr = sk->sk_v6_daddr; 233 fl6.saddr = saddr ? *saddr : np->saddr; 234 fl6.flowi6_oif = sk->sk_bound_dev_if; 235 fl6.flowi6_mark = sk->sk_mark; 236 fl6.fl6_dport = usin->sin6_port; 237 fl6.fl6_sport = inet->inet_sport; 238 | 123 struct flowi6 fl6; 124 struct dst_entry *dst; 125 int addr_type; 126 int err; 127 128 if (addr_len < SIN6_LEN_RFC2133) 129 return -EINVAL; 130 --- 99 unchanged lines hidden (view full) --- 230 fl6.flowi6_proto = IPPROTO_TCP; 231 fl6.daddr = sk->sk_v6_daddr; 232 fl6.saddr = saddr ? *saddr : np->saddr; 233 fl6.flowi6_oif = sk->sk_bound_dev_if; 234 fl6.flowi6_mark = sk->sk_mark; 235 fl6.fl6_dport = usin->sin6_port; 236 fl6.fl6_sport = inet->inet_sport; 237 |
239 opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); 240 final_p = fl6_update_dst(&fl6, opt, &final); | 238 final_p = fl6_update_dst(&fl6, np->opt, &final); |
241 242 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); 243 244 dst = ip6_dst_lookup_flow(sk, &fl6, final_p); 245 if (IS_ERR(dst)) { 246 err = PTR_ERR(dst); 247 goto failure; 248 } --- 11 unchanged lines hidden (view full) --- 260 __ip6_dst_store(sk, dst, NULL, NULL); 261 262 if (tcp_death_row.sysctl_tw_recycle && 263 !tp->rx_opt.ts_recent_stamp && 264 ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr)) 265 tcp_fetch_timewait_stamp(sk, dst); 266 267 icsk->icsk_ext_hdr_len = 0; | 239 240 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); 241 242 dst = ip6_dst_lookup_flow(sk, &fl6, final_p); 243 if (IS_ERR(dst)) { 244 err = PTR_ERR(dst); 245 goto failure; 246 } --- 11 unchanged lines hidden (view full) --- 258 __ip6_dst_store(sk, dst, NULL, NULL); 259 260 if (tcp_death_row.sysctl_tw_recycle && 261 !tp->rx_opt.ts_recent_stamp && 262 ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr)) 263 tcp_fetch_timewait_stamp(sk, dst); 264 265 icsk->icsk_ext_hdr_len = 0; |
268 if (opt) 269 icsk->icsk_ext_hdr_len = opt->opt_flen + 270 opt->opt_nflen; | 266 if (np->opt) 267 icsk->icsk_ext_hdr_len = (np->opt->opt_flen + 268 np->opt->opt_nflen); |
271 272 tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 273 274 inet->inet_dport = usin->sin6_port; 275 276 tcp_set_state(sk, TCP_SYN_SENT); 277 err = inet6_hash_connect(&tcp_death_row, sk); 278 if (err) --- 179 unchanged lines hidden (view full) --- 458 if (skb) { 459 __tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr, 460 &ireq->ir_v6_rmt_addr); 461 462 fl6->daddr = ireq->ir_v6_rmt_addr; 463 if (np->repflow && ireq->pktopts) 464 fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); 465 | 269 270 tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 271 272 inet->inet_dport = usin->sin6_port; 273 274 tcp_set_state(sk, TCP_SYN_SENT); 275 err = inet6_hash_connect(&tcp_death_row, sk); 276 if (err) --- 179 unchanged lines hidden (view full) --- 456 if (skb) { 457 __tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr, 458 &ireq->ir_v6_rmt_addr); 459 460 fl6->daddr = ireq->ir_v6_rmt_addr; 461 if (np->repflow && ireq->pktopts) 462 fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); 463 |
466 err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt), 467 np->tclass); | 464 err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass); |
468 err = net_xmit_eval(err); 469 } 470 471done: 472 return err; 473} 474 475 --- 494 unchanged lines hidden (view full) --- 970 struct request_sock *req, 971 struct dst_entry *dst, 972 struct request_sock *req_unhash, 973 bool *own_req) 974{ 975 struct inet_request_sock *ireq; 976 struct ipv6_pinfo *newnp; 977 const struct ipv6_pinfo *np = inet6_sk(sk); | 465 err = net_xmit_eval(err); 466 } 467 468done: 469 return err; 470} 471 472 --- 494 unchanged lines hidden (view full) --- 967 struct request_sock *req, 968 struct dst_entry *dst, 969 struct request_sock *req_unhash, 970 bool *own_req) 971{ 972 struct inet_request_sock *ireq; 973 struct ipv6_pinfo *newnp; 974 const struct ipv6_pinfo *np = inet6_sk(sk); |
978 struct ipv6_txoptions *opt; | |
979 struct tcp6_sock *newtcp6sk; 980 struct inet_sock *newinet; 981 struct tcp_sock *newtp; 982 struct sock *newsk; 983#ifdef CONFIG_TCP_MD5SIG 984 struct tcp_md5sig_key *key; 985#endif 986 struct flowi6 fl6; --- 110 unchanged lines hidden (view full) --- 1097 newnp->flow_label = ip6_flowlabel(ipv6_hdr(skb)); 1098 1099 /* Clone native IPv6 options from listening socket (if any) 1100 1101 Yes, keeping reference count would be much more clever, 1102 but we make one more one thing there: reattach optmem 1103 to newsk. 1104 */ | 975 struct tcp6_sock *newtcp6sk; 976 struct inet_sock *newinet; 977 struct tcp_sock *newtp; 978 struct sock *newsk; 979#ifdef CONFIG_TCP_MD5SIG 980 struct tcp_md5sig_key *key; 981#endif 982 struct flowi6 fl6; --- 110 unchanged lines hidden (view full) --- 1093 newnp->flow_label = ip6_flowlabel(ipv6_hdr(skb)); 1094 1095 /* Clone native IPv6 options from listening socket (if any) 1096 1097 Yes, keeping reference count would be much more clever, 1098 but we make one more one thing there: reattach optmem 1099 to newsk. 1100 */ |
1105 opt = rcu_dereference(np->opt); 1106 if (opt) { 1107 opt = ipv6_dup_options(newsk, opt); 1108 RCU_INIT_POINTER(newnp->opt, opt); 1109 } | 1101 if (np->opt) 1102 newnp->opt = ipv6_dup_options(newsk, np->opt); 1103 |
1110 inet_csk(newsk)->icsk_ext_hdr_len = 0; | 1104 inet_csk(newsk)->icsk_ext_hdr_len = 0; |
1111 if (opt) 1112 inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + 1113 opt->opt_flen; | 1105 if (newnp->opt) 1106 inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + 1107 newnp->opt->opt_flen); |
1114 1115 tcp_ca_openreq_child(newsk, dst); 1116 1117 tcp_sync_mss(newsk, dst_mtu(dst)); 1118 newtp->advmss = dst_metric_advmss(dst); 1119 if (tcp_sk(sk)->rx_opt.user_mss && 1120 tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) 1121 newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; --- 9 unchanged lines hidden (view full) --- 1131 if (key) { 1132 /* We're using one, so create a matching key 1133 * on the newsk structure. If we fail to get 1134 * memory, then we end up not copying the key 1135 * across. Shucks. 1136 */ 1137 tcp_md5_do_add(newsk, (union tcp_md5_addr *)&newsk->sk_v6_daddr, 1138 AF_INET6, key->key, key->keylen, | 1108 1109 tcp_ca_openreq_child(newsk, dst); 1110 1111 tcp_sync_mss(newsk, dst_mtu(dst)); 1112 newtp->advmss = dst_metric_advmss(dst); 1113 if (tcp_sk(sk)->rx_opt.user_mss && 1114 tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) 1115 newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; --- 9 unchanged lines hidden (view full) --- 1125 if (key) { 1126 /* We're using one, so create a matching key 1127 * on the newsk structure. If we fail to get 1128 * memory, then we end up not copying the key 1129 * across. Shucks. 1130 */ 1131 tcp_md5_do_add(newsk, (union tcp_md5_addr *)&newsk->sk_v6_daddr, 1132 AF_INET6, key->key, key->keylen, |
1139 sk_gfp_atomic(sk, GFP_ATOMIC)); | 1133 sk_gfp_mask(sk, GFP_ATOMIC)); |
1140 } 1141#endif 1142 1143 if (__inet_inherit_port(sk, newsk) < 0) { 1144 inet_csk_prepare_forced_close(newsk); 1145 tcp_done(newsk); 1146 goto out; 1147 } 1148 *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); 1149 if (*own_req) { 1150 tcp_move_syn(newtp, req); 1151 1152 /* Clone pktoptions received with SYN, if we own the req */ 1153 if (ireq->pktopts) { 1154 newnp->pktoptions = skb_clone(ireq->pktopts, | 1134 } 1135#endif 1136 1137 if (__inet_inherit_port(sk, newsk) < 0) { 1138 inet_csk_prepare_forced_close(newsk); 1139 tcp_done(newsk); 1140 goto out; 1141 } 1142 *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); 1143 if (*own_req) { 1144 tcp_move_syn(newtp, req); 1145 1146 /* Clone pktoptions received with SYN, if we own the req */ 1147 if (ireq->pktopts) { 1148 newnp->pktoptions = skb_clone(ireq->pktopts, |
1155 sk_gfp_atomic(sk, GFP_ATOMIC)); | 1149 sk_gfp_mask(sk, GFP_ATOMIC)); |
1156 consume_skb(ireq->pktopts); 1157 ireq->pktopts = NULL; 1158 if (newnp->pktoptions) 1159 skb_set_owner_r(newnp->pktoptions, newsk); 1160 } 1161 } 1162 1163 return newsk; --- 49 unchanged lines hidden (view full) --- 1213 1214 Actually, all the idea behind IPV6_PKTOPTIONS 1215 looks not very well thought. For now we latch 1216 options, received in the last packet, enqueued 1217 by tcp. Feel free to propose better solution. 1218 --ANK (980728) 1219 */ 1220 if (np->rxopt.all) | 1150 consume_skb(ireq->pktopts); 1151 ireq->pktopts = NULL; 1152 if (newnp->pktoptions) 1153 skb_set_owner_r(newnp->pktoptions, newsk); 1154 } 1155 } 1156 1157 return newsk; --- 49 unchanged lines hidden (view full) --- 1207 1208 Actually, all the idea behind IPV6_PKTOPTIONS 1209 looks not very well thought. For now we latch 1210 options, received in the last packet, enqueued 1211 by tcp. Feel free to propose better solution. 1212 --ANK (980728) 1213 */ 1214 if (np->rxopt.all) |
1221 opt_skb = skb_clone(skb, sk_gfp_atomic(sk, GFP_ATOMIC)); | 1215 opt_skb = skb_clone(skb, sk_gfp_mask(sk, GFP_ATOMIC)); |
1222 1223 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ 1224 struct dst_entry *dst = sk->sk_rx_dst; 1225 1226 sock_rps_save_rxhash(sk, skb); 1227 sk_mark_napi_id(sk, skb); 1228 if (dst) { 1229 if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || --- 735 unchanged lines hidden --- | 1216 1217 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ 1218 struct dst_entry *dst = sk->sk_rx_dst; 1219 1220 sock_rps_save_rxhash(sk, skb); 1221 sk_mark_napi_id(sk, skb); 1222 if (dst) { 1223 if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || --- 735 unchanged lines hidden --- |