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