tcp_ipv6.c (0eea505058740aa45486145296ef4fefbd8cab85) | tcp_ipv6.c (45f6fad84cc305103b28d73482b344d7f5b76f39) |
---|---|
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; |
|
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 | 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 |
238 final_p = fl6_update_dst(&fl6, np->opt, &final); | 239 opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); 240 final_p = fl6_update_dst(&fl6, opt, &final); |
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; | 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; |
266 if (np->opt) 267 icsk->icsk_ext_hdr_len = (np->opt->opt_flen + 268 np->opt->opt_nflen); | 268 if (opt) 269 icsk->icsk_ext_hdr_len = opt->opt_flen + 270 opt->opt_nflen; |
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 | 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 |
464 err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass); | 466 err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt), 467 np->tclass); |
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); | 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); |
978 struct ipv6_txoptions *opt; |
|
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 */ | 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 */ |
1101 if (np->opt) 1102 newnp->opt = ipv6_dup_options(newsk, np->opt); 1103 | 1105 opt = rcu_dereference(np->opt); 1106 if (opt) { 1107 opt = ipv6_dup_options(newsk, opt); 1108 RCU_INIT_POINTER(newnp->opt, opt); 1109 } |
1104 inet_csk(newsk)->icsk_ext_hdr_len = 0; | 1110 inet_csk(newsk)->icsk_ext_hdr_len = 0; |
1105 if (newnp->opt) 1106 inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + 1107 newnp->opt->opt_flen); | 1111 if (opt) 1112 inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + 1113 opt->opt_flen; |
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; --- 843 unchanged lines hidden --- | 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; --- 843 unchanged lines hidden --- |