diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 204 |
1 files changed, 56 insertions, 148 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 9df64a50b075..f49476e2d884 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -277,22 +277,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
277 | rt = (struct rt6_info *) dst; | 277 | rt = (struct rt6_info *) dst; |
278 | if (tcp_death_row.sysctl_tw_recycle && | 278 | if (tcp_death_row.sysctl_tw_recycle && |
279 | !tp->rx_opt.ts_recent_stamp && | 279 | !tp->rx_opt.ts_recent_stamp && |
280 | ipv6_addr_equal(&rt->rt6i_dst.addr, &np->daddr)) { | 280 | ipv6_addr_equal(&rt->rt6i_dst.addr, &np->daddr)) |
281 | struct inet_peer *peer = rt6_get_peer(rt); | 281 | tcp_fetch_timewait_stamp(sk, dst); |
282 | /* | ||
283 | * VJ's idea. We save last timestamp seen from | ||
284 | * the destination in peer table, when entering state | ||
285 | * TIME-WAIT * and initialize rx_opt.ts_recent from it, | ||
286 | * when trying new connection. | ||
287 | */ | ||
288 | if (peer) { | ||
289 | inet_peer_refcheck(peer); | ||
290 | if ((u32)get_seconds() - peer->tcp_ts_stamp <= TCP_PAWS_MSL) { | ||
291 | tp->rx_opt.ts_recent_stamp = peer->tcp_ts_stamp; | ||
292 | tp->rx_opt.ts_recent = peer->tcp_ts; | ||
293 | } | ||
294 | } | ||
295 | } | ||
296 | 282 | ||
297 | icsk->icsk_ext_hdr_len = 0; | 283 | icsk->icsk_ext_hdr_len = 0; |
298 | if (np->opt) | 284 | if (np->opt) |
@@ -329,6 +315,23 @@ failure: | |||
329 | return err; | 315 | return err; |
330 | } | 316 | } |
331 | 317 | ||
318 | static void tcp_v6_mtu_reduced(struct sock *sk) | ||
319 | { | ||
320 | struct dst_entry *dst; | ||
321 | |||
322 | if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) | ||
323 | return; | ||
324 | |||
325 | dst = inet6_csk_update_pmtu(sk, tcp_sk(sk)->mtu_info); | ||
326 | if (!dst) | ||
327 | return; | ||
328 | |||
329 | if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { | ||
330 | tcp_sync_mss(sk, dst_mtu(dst)); | ||
331 | tcp_simple_retransmit(sk); | ||
332 | } | ||
333 | } | ||
334 | |||
332 | static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | 335 | static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
333 | u8 type, u8 code, int offset, __be32 info) | 336 | u8 type, u8 code, int offset, __be32 info) |
334 | { | 337 | { |
@@ -356,7 +359,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
356 | } | 359 | } |
357 | 360 | ||
358 | bh_lock_sock(sk); | 361 | bh_lock_sock(sk); |
359 | if (sock_owned_by_user(sk)) | 362 | if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG) |
360 | NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS); | 363 | NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS); |
361 | 364 | ||
362 | if (sk->sk_state == TCP_CLOSE) | 365 | if (sk->sk_state == TCP_CLOSE) |
@@ -377,49 +380,19 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
377 | 380 | ||
378 | np = inet6_sk(sk); | 381 | np = inet6_sk(sk); |
379 | 382 | ||
380 | if (type == ICMPV6_PKT_TOOBIG) { | 383 | if (type == NDISC_REDIRECT) { |
381 | struct dst_entry *dst; | 384 | struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); |
382 | |||
383 | if (sock_owned_by_user(sk)) | ||
384 | goto out; | ||
385 | if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) | ||
386 | goto out; | ||
387 | |||
388 | /* icmp should have updated the destination cache entry */ | ||
389 | dst = __sk_dst_check(sk, np->dst_cookie); | ||
390 | |||
391 | if (dst == NULL) { | ||
392 | struct inet_sock *inet = inet_sk(sk); | ||
393 | struct flowi6 fl6; | ||
394 | |||
395 | /* BUGGG_FUTURE: Again, it is not clear how | ||
396 | to handle rthdr case. Ignore this complexity | ||
397 | for now. | ||
398 | */ | ||
399 | memset(&fl6, 0, sizeof(fl6)); | ||
400 | fl6.flowi6_proto = IPPROTO_TCP; | ||
401 | fl6.daddr = np->daddr; | ||
402 | fl6.saddr = np->saddr; | ||
403 | fl6.flowi6_oif = sk->sk_bound_dev_if; | ||
404 | fl6.flowi6_mark = sk->sk_mark; | ||
405 | fl6.fl6_dport = inet->inet_dport; | ||
406 | fl6.fl6_sport = inet->inet_sport; | ||
407 | security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); | ||
408 | |||
409 | dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false); | ||
410 | if (IS_ERR(dst)) { | ||
411 | sk->sk_err_soft = -PTR_ERR(dst); | ||
412 | goto out; | ||
413 | } | ||
414 | 385 | ||
415 | } else | 386 | if (dst) |
416 | dst_hold(dst); | 387 | dst->ops->redirect(dst, sk, skb); |
388 | } | ||
417 | 389 | ||
418 | if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { | 390 | if (type == ICMPV6_PKT_TOOBIG) { |
419 | tcp_sync_mss(sk, dst_mtu(dst)); | 391 | tp->mtu_info = ntohl(info); |
420 | tcp_simple_retransmit(sk); | 392 | if (!sock_owned_by_user(sk)) |
421 | } /* else let the usual retransmit timer handle it */ | 393 | tcp_v6_mtu_reduced(sk); |
422 | dst_release(dst); | 394 | else |
395 | set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags); | ||
423 | goto out; | 396 | goto out; |
424 | } | 397 | } |
425 | 398 | ||
@@ -475,62 +448,43 @@ out: | |||
475 | } | 448 | } |
476 | 449 | ||
477 | 450 | ||
478 | static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | 451 | static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, |
452 | struct flowi6 *fl6, | ||
453 | struct request_sock *req, | ||
479 | struct request_values *rvp, | 454 | struct request_values *rvp, |
480 | u16 queue_mapping) | 455 | u16 queue_mapping) |
481 | { | 456 | { |
482 | struct inet6_request_sock *treq = inet6_rsk(req); | 457 | struct inet6_request_sock *treq = inet6_rsk(req); |
483 | struct ipv6_pinfo *np = inet6_sk(sk); | 458 | struct ipv6_pinfo *np = inet6_sk(sk); |
484 | struct sk_buff * skb; | 459 | struct sk_buff * skb; |
485 | struct ipv6_txoptions *opt = NULL; | 460 | int err = -ENOMEM; |
486 | struct in6_addr * final_p, final; | ||
487 | struct flowi6 fl6; | ||
488 | struct dst_entry *dst; | ||
489 | int err; | ||
490 | 461 | ||
491 | memset(&fl6, 0, sizeof(fl6)); | 462 | /* First, grab a route. */ |
492 | fl6.flowi6_proto = IPPROTO_TCP; | 463 | if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) |
493 | fl6.daddr = treq->rmt_addr; | ||
494 | fl6.saddr = treq->loc_addr; | ||
495 | fl6.flowlabel = 0; | ||
496 | fl6.flowi6_oif = treq->iif; | ||
497 | fl6.flowi6_mark = sk->sk_mark; | ||
498 | fl6.fl6_dport = inet_rsk(req)->rmt_port; | ||
499 | fl6.fl6_sport = inet_rsk(req)->loc_port; | ||
500 | security_req_classify_flow(req, flowi6_to_flowi(&fl6)); | ||
501 | |||
502 | opt = np->opt; | ||
503 | final_p = fl6_update_dst(&fl6, opt, &final); | ||
504 | |||
505 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); | ||
506 | if (IS_ERR(dst)) { | ||
507 | err = PTR_ERR(dst); | ||
508 | dst = NULL; | ||
509 | goto done; | 464 | goto done; |
510 | } | 465 | |
511 | skb = tcp_make_synack(sk, dst, req, rvp); | 466 | skb = tcp_make_synack(sk, dst, req, rvp); |
512 | err = -ENOMEM; | 467 | |
513 | if (skb) { | 468 | if (skb) { |
514 | __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); | 469 | __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); |
515 | 470 | ||
516 | fl6.daddr = treq->rmt_addr; | 471 | fl6->daddr = treq->rmt_addr; |
517 | skb_set_queue_mapping(skb, queue_mapping); | 472 | skb_set_queue_mapping(skb, queue_mapping); |
518 | err = ip6_xmit(sk, skb, &fl6, opt, np->tclass); | 473 | err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass); |
519 | err = net_xmit_eval(err); | 474 | err = net_xmit_eval(err); |
520 | } | 475 | } |
521 | 476 | ||
522 | done: | 477 | done: |
523 | if (opt && opt != np->opt) | ||
524 | sock_kfree_s(sk, opt, opt->tot_len); | ||
525 | dst_release(dst); | ||
526 | return err; | 478 | return err; |
527 | } | 479 | } |
528 | 480 | ||
529 | static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, | 481 | static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, |
530 | struct request_values *rvp) | 482 | struct request_values *rvp) |
531 | { | 483 | { |
484 | struct flowi6 fl6; | ||
485 | |||
532 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); | 486 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); |
533 | return tcp_v6_send_synack(sk, req, rvp, 0); | 487 | return tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); |
534 | } | 488 | } |
535 | 489 | ||
536 | static void tcp_v6_reqsk_destructor(struct request_sock *req) | 490 | static void tcp_v6_reqsk_destructor(struct request_sock *req) |
@@ -1057,6 +1011,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1057 | struct tcp_sock *tp = tcp_sk(sk); | 1011 | struct tcp_sock *tp = tcp_sk(sk); |
1058 | __u32 isn = TCP_SKB_CB(skb)->when; | 1012 | __u32 isn = TCP_SKB_CB(skb)->when; |
1059 | struct dst_entry *dst = NULL; | 1013 | struct dst_entry *dst = NULL; |
1014 | struct flowi6 fl6; | ||
1060 | bool want_cookie = false; | 1015 | bool want_cookie = false; |
1061 | 1016 | ||
1062 | if (skb->protocol == htons(ETH_P_IP)) | 1017 | if (skb->protocol == htons(ETH_P_IP)) |
@@ -1085,7 +1040,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1085 | tcp_clear_options(&tmp_opt); | 1040 | tcp_clear_options(&tmp_opt); |
1086 | tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); | 1041 | tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); |
1087 | tmp_opt.user_mss = tp->rx_opt.user_mss; | 1042 | tmp_opt.user_mss = tp->rx_opt.user_mss; |
1088 | tcp_parse_options(skb, &tmp_opt, &hash_location, 0); | 1043 | tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL); |
1089 | 1044 | ||
1090 | if (tmp_opt.cookie_plus > 0 && | 1045 | if (tmp_opt.cookie_plus > 0 && |
1091 | tmp_opt.saw_tstamp && | 1046 | tmp_opt.saw_tstamp && |
@@ -1150,8 +1105,6 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1150 | treq->iif = inet6_iif(skb); | 1105 | treq->iif = inet6_iif(skb); |
1151 | 1106 | ||
1152 | if (!isn) { | 1107 | if (!isn) { |
1153 | struct inet_peer *peer = NULL; | ||
1154 | |||
1155 | if (ipv6_opt_accepted(sk, skb) || | 1108 | if (ipv6_opt_accepted(sk, skb) || |
1156 | np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || | 1109 | np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || |
1157 | np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { | 1110 | np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { |
@@ -1176,14 +1129,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1176 | */ | 1129 | */ |
1177 | if (tmp_opt.saw_tstamp && | 1130 | if (tmp_opt.saw_tstamp && |
1178 | tcp_death_row.sysctl_tw_recycle && | 1131 | tcp_death_row.sysctl_tw_recycle && |
1179 | (dst = inet6_csk_route_req(sk, req)) != NULL && | 1132 | (dst = inet6_csk_route_req(sk, &fl6, req)) != NULL) { |
1180 | (peer = rt6_get_peer((struct rt6_info *)dst)) != NULL && | 1133 | if (!tcp_peer_is_proven(req, dst, true)) { |
1181 | ipv6_addr_equal((struct in6_addr *)peer->daddr.addr.a6, | ||
1182 | &treq->rmt_addr)) { | ||
1183 | inet_peer_refcheck(peer); | ||
1184 | if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL && | ||
1185 | (s32)(peer->tcp_ts - req->ts_recent) > | ||
1186 | TCP_PAWS_WINDOW) { | ||
1187 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED); | 1134 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED); |
1188 | goto drop_and_release; | 1135 | goto drop_and_release; |
1189 | } | 1136 | } |
@@ -1192,8 +1139,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1192 | else if (!sysctl_tcp_syncookies && | 1139 | else if (!sysctl_tcp_syncookies && |
1193 | (sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) < | 1140 | (sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) < |
1194 | (sysctl_max_syn_backlog >> 2)) && | 1141 | (sysctl_max_syn_backlog >> 2)) && |
1195 | (!peer || !peer->tcp_ts_stamp) && | 1142 | !tcp_peer_is_proven(req, dst, false)) { |
1196 | (!dst || !dst_metric(dst, RTAX_RTT))) { | ||
1197 | /* Without syncookies last quarter of | 1143 | /* Without syncookies last quarter of |
1198 | * backlog is filled with destinations, | 1144 | * backlog is filled with destinations, |
1199 | * proven to be alive. | 1145 | * proven to be alive. |
@@ -1215,7 +1161,7 @@ have_isn: | |||
1215 | if (security_inet_conn_request(sk, skb, req)) | 1161 | if (security_inet_conn_request(sk, skb, req)) |
1216 | goto drop_and_release; | 1162 | goto drop_and_release; |
1217 | 1163 | ||
1218 | if (tcp_v6_send_synack(sk, req, | 1164 | if (tcp_v6_send_synack(sk, dst, &fl6, req, |
1219 | (struct request_values *)&tmp_ext, | 1165 | (struct request_values *)&tmp_ext, |
1220 | skb_get_queue_mapping(skb)) || | 1166 | skb_get_queue_mapping(skb)) || |
1221 | want_cookie) | 1167 | want_cookie) |
@@ -1242,10 +1188,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1242 | struct inet_sock *newinet; | 1188 | struct inet_sock *newinet; |
1243 | struct tcp_sock *newtp; | 1189 | struct tcp_sock *newtp; |
1244 | struct sock *newsk; | 1190 | struct sock *newsk; |
1245 | struct ipv6_txoptions *opt; | ||
1246 | #ifdef CONFIG_TCP_MD5SIG | 1191 | #ifdef CONFIG_TCP_MD5SIG |
1247 | struct tcp_md5sig_key *key; | 1192 | struct tcp_md5sig_key *key; |
1248 | #endif | 1193 | #endif |
1194 | struct flowi6 fl6; | ||
1249 | 1195 | ||
1250 | if (skb->protocol == htons(ETH_P_IP)) { | 1196 | if (skb->protocol == htons(ETH_P_IP)) { |
1251 | /* | 1197 | /* |
@@ -1302,13 +1248,12 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1302 | } | 1248 | } |
1303 | 1249 | ||
1304 | treq = inet6_rsk(req); | 1250 | treq = inet6_rsk(req); |
1305 | opt = np->opt; | ||
1306 | 1251 | ||
1307 | if (sk_acceptq_is_full(sk)) | 1252 | if (sk_acceptq_is_full(sk)) |
1308 | goto out_overflow; | 1253 | goto out_overflow; |
1309 | 1254 | ||
1310 | if (!dst) { | 1255 | if (!dst) { |
1311 | dst = inet6_csk_route_req(sk, req); | 1256 | dst = inet6_csk_route_req(sk, &fl6, req); |
1312 | if (!dst) | 1257 | if (!dst) |
1313 | goto out; | 1258 | goto out; |
1314 | } | 1259 | } |
@@ -1371,11 +1316,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1371 | but we make one more one thing there: reattach optmem | 1316 | but we make one more one thing there: reattach optmem |
1372 | to newsk. | 1317 | to newsk. |
1373 | */ | 1318 | */ |
1374 | if (opt) { | 1319 | if (np->opt) |
1375 | newnp->opt = ipv6_dup_options(newsk, opt); | 1320 | newnp->opt = ipv6_dup_options(newsk, np->opt); |
1376 | if (opt != np->opt) | ||
1377 | sock_kfree_s(sk, opt, opt->tot_len); | ||
1378 | } | ||
1379 | 1321 | ||
1380 | inet_csk(newsk)->icsk_ext_hdr_len = 0; | 1322 | inet_csk(newsk)->icsk_ext_hdr_len = 0; |
1381 | if (newnp->opt) | 1323 | if (newnp->opt) |
@@ -1422,8 +1364,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1422 | out_overflow: | 1364 | out_overflow: |
1423 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); | 1365 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); |
1424 | out_nonewsk: | 1366 | out_nonewsk: |
1425 | if (opt && opt != np->opt) | ||
1426 | sock_kfree_s(sk, opt, opt->tot_len); | ||
1427 | dst_release(dst); | 1367 | dst_release(dst); |
1428 | out: | 1368 | out: |
1429 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); | 1369 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); |
@@ -1734,42 +1674,10 @@ do_time_wait: | |||
1734 | goto discard_it; | 1674 | goto discard_it; |
1735 | } | 1675 | } |
1736 | 1676 | ||
1737 | static struct inet_peer *tcp_v6_get_peer(struct sock *sk, bool *release_it) | ||
1738 | { | ||
1739 | struct rt6_info *rt = (struct rt6_info *) __sk_dst_get(sk); | ||
1740 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
1741 | struct inet_peer *peer; | ||
1742 | |||
1743 | if (!rt || | ||
1744 | !ipv6_addr_equal(&np->daddr, &rt->rt6i_dst.addr)) { | ||
1745 | peer = inet_getpeer_v6(&np->daddr, 1); | ||
1746 | *release_it = true; | ||
1747 | } else { | ||
1748 | if (!rt->rt6i_peer) | ||
1749 | rt6_bind_peer(rt, 1); | ||
1750 | peer = rt->rt6i_peer; | ||
1751 | *release_it = false; | ||
1752 | } | ||
1753 | |||
1754 | return peer; | ||
1755 | } | ||
1756 | |||
1757 | static void *tcp_v6_tw_get_peer(struct sock *sk) | ||
1758 | { | ||
1759 | const struct inet6_timewait_sock *tw6 = inet6_twsk(sk); | ||
1760 | const struct inet_timewait_sock *tw = inet_twsk(sk); | ||
1761 | |||
1762 | if (tw->tw_family == AF_INET) | ||
1763 | return tcp_v4_tw_get_peer(sk); | ||
1764 | |||
1765 | return inet_getpeer_v6(&tw6->tw_v6_daddr, 1); | ||
1766 | } | ||
1767 | |||
1768 | static struct timewait_sock_ops tcp6_timewait_sock_ops = { | 1677 | static struct timewait_sock_ops tcp6_timewait_sock_ops = { |
1769 | .twsk_obj_size = sizeof(struct tcp6_timewait_sock), | 1678 | .twsk_obj_size = sizeof(struct tcp6_timewait_sock), |
1770 | .twsk_unique = tcp_twsk_unique, | 1679 | .twsk_unique = tcp_twsk_unique, |
1771 | .twsk_destructor= tcp_twsk_destructor, | 1680 | .twsk_destructor= tcp_twsk_destructor, |
1772 | .twsk_getpeer = tcp_v6_tw_get_peer, | ||
1773 | }; | 1681 | }; |
1774 | 1682 | ||
1775 | static const struct inet_connection_sock_af_ops ipv6_specific = { | 1683 | static const struct inet_connection_sock_af_ops ipv6_specific = { |
@@ -1778,7 +1686,6 @@ static const struct inet_connection_sock_af_ops ipv6_specific = { | |||
1778 | .rebuild_header = inet6_sk_rebuild_header, | 1686 | .rebuild_header = inet6_sk_rebuild_header, |
1779 | .conn_request = tcp_v6_conn_request, | 1687 | .conn_request = tcp_v6_conn_request, |
1780 | .syn_recv_sock = tcp_v6_syn_recv_sock, | 1688 | .syn_recv_sock = tcp_v6_syn_recv_sock, |
1781 | .get_peer = tcp_v6_get_peer, | ||
1782 | .net_header_len = sizeof(struct ipv6hdr), | 1689 | .net_header_len = sizeof(struct ipv6hdr), |
1783 | .net_frag_header_len = sizeof(struct frag_hdr), | 1690 | .net_frag_header_len = sizeof(struct frag_hdr), |
1784 | .setsockopt = ipv6_setsockopt, | 1691 | .setsockopt = ipv6_setsockopt, |
@@ -1810,7 +1717,6 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = { | |||
1810 | .rebuild_header = inet_sk_rebuild_header, | 1717 | .rebuild_header = inet_sk_rebuild_header, |
1811 | .conn_request = tcp_v6_conn_request, | 1718 | .conn_request = tcp_v6_conn_request, |
1812 | .syn_recv_sock = tcp_v6_syn_recv_sock, | 1719 | .syn_recv_sock = tcp_v6_syn_recv_sock, |
1813 | .get_peer = tcp_v4_get_peer, | ||
1814 | .net_header_len = sizeof(struct iphdr), | 1720 | .net_header_len = sizeof(struct iphdr), |
1815 | .setsockopt = ipv6_setsockopt, | 1721 | .setsockopt = ipv6_setsockopt, |
1816 | .getsockopt = ipv6_getsockopt, | 1722 | .getsockopt = ipv6_getsockopt, |
@@ -2049,6 +1955,8 @@ struct proto tcpv6_prot = { | |||
2049 | .sendmsg = tcp_sendmsg, | 1955 | .sendmsg = tcp_sendmsg, |
2050 | .sendpage = tcp_sendpage, | 1956 | .sendpage = tcp_sendpage, |
2051 | .backlog_rcv = tcp_v6_do_rcv, | 1957 | .backlog_rcv = tcp_v6_do_rcv, |
1958 | .release_cb = tcp_release_cb, | ||
1959 | .mtu_reduced = tcp_v6_mtu_reduced, | ||
2052 | .hash = tcp_v6_hash, | 1960 | .hash = tcp_v6_hash, |
2053 | .unhash = inet_unhash, | 1961 | .unhash = inet_unhash, |
2054 | .get_port = inet_csk_get_port, | 1962 | .get_port = inet_csk_get_port, |