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 ---