aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/dccp.h4
-rw-r--r--include/linux/ip.h1
-rw-r--r--include/linux/tcp.h3
-rw-r--r--include/net/inet_connection_sock.h6
-rw-r--r--include/net/protocol.h1
-rw-r--r--net/dccp/diag.c2
-rw-r--r--net/dccp/input.c2
-rw-r--r--net/dccp/ipv4.c12
-rw-r--r--net/dccp/ipv6.c26
-rw-r--r--net/dccp/output.c7
-rw-r--r--net/dccp/proto.c2
-rw-r--r--net/ipv4/af_inet.c4
-rw-r--r--net/ipv4/ip_sockglue.c13
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/tcp_input.c10
-rw-r--r--net/ipv4/tcp_ipv4.c12
-rw-r--r--net/ipv4/tcp_output.c18
-rw-r--r--net/ipv6/af_inet6.c1
-rw-r--r--net/ipv6/ipv6_sockglue.c24
-rw-r--r--net/ipv6/tcp_ipv6.c30
20 files changed, 97 insertions, 83 deletions
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 71fab4311e92..d0bdb499cf8d 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -408,8 +408,6 @@ struct dccp_ackvec;
408 * @dccps_gar - greatest valid ack number received on a non-Sync; initialized to %dccps_iss 408 * @dccps_gar - greatest valid ack number received on a non-Sync; initialized to %dccps_iss
409 * @dccps_timestamp_time - time of latest TIMESTAMP option 409 * @dccps_timestamp_time - time of latest TIMESTAMP option
410 * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option 410 * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option
411 * @dccps_ext_header_len - network protocol overhead (IP/IPv6 options)
412 * @dccps_pmtu_cookie - Last pmtu seen by socket
413 * @dccps_packet_size - Set thru setsockopt 411 * @dccps_packet_size - Set thru setsockopt
414 * @dccps_role - Role of this sock, one of %dccp_role 412 * @dccps_role - Role of this sock, one of %dccp_role
415 * @dccps_ndp_count - number of Non Data Packets since last data packet 413 * @dccps_ndp_count - number of Non Data Packets since last data packet
@@ -434,8 +432,6 @@ struct dccp_sock {
434 __u32 dccps_timestamp_echo; 432 __u32 dccps_timestamp_echo;
435 __u32 dccps_packet_size; 433 __u32 dccps_packet_size;
436 unsigned long dccps_ndp_count; 434 unsigned long dccps_ndp_count;
437 __u16 dccps_ext_header_len;
438 __u32 dccps_pmtu_cookie;
439 __u32 dccps_mss_cache; 435 __u32 dccps_mss_cache;
440 struct dccp_options dccps_options; 436 struct dccp_options dccps_options;
441 struct dccp_ackvec *dccps_hc_rx_ackvec; 437 struct dccp_ackvec *dccps_hc_rx_ackvec;
diff --git a/include/linux/ip.h b/include/linux/ip.h
index 5a560daeade5..6ccc596c19c8 100644
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -155,6 +155,7 @@ struct inet_sock {
155 __u8 mc_ttl; /* Multicasting TTL */ 155 __u8 mc_ttl; /* Multicasting TTL */
156 __u8 pmtudisc; 156 __u8 pmtudisc;
157 unsigned recverr : 1, 157 unsigned recverr : 1,
158 is_icsk : 1, /* inet_connection_sock? */
158 freebind : 1, 159 freebind : 1,
159 hdrincl : 1, 160 hdrincl : 1,
160 mc_loop : 1; 161 mc_loop : 1;
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index da38eea1994b..f2bb2396853f 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -238,10 +238,9 @@ struct tcp_sock {
238 __u32 snd_wl1; /* Sequence for window update */ 238 __u32 snd_wl1; /* Sequence for window update */
239 __u32 snd_wnd; /* The window we expect to receive */ 239 __u32 snd_wnd; /* The window we expect to receive */
240 __u32 max_window; /* Maximal window ever seen from peer */ 240 __u32 max_window; /* Maximal window ever seen from peer */
241 __u32 pmtu_cookie; /* Last pmtu seen by socket */
242 __u32 mss_cache; /* Cached effective mss, not including SACKS */ 241 __u32 mss_cache; /* Cached effective mss, not including SACKS */
243 __u16 xmit_size_goal; /* Goal for segmenting output packets */ 242 __u16 xmit_size_goal; /* Goal for segmenting output packets */
244 __u16 ext_header_len; /* Network protocol overhead (IP/IPv6 options) */ 243 /* XXX Two bytes hole, try to pack */
245 244
246 __u32 window_clamp; /* Maximal window to advertise */ 245 __u32 window_clamp; /* Maximal window to advertise */
247 __u32 rcv_ssthresh; /* Current window clamp */ 246 __u32 rcv_ssthresh; /* Current window clamp */
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index e50e2b890c6d..91888967d3e3 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -60,6 +60,7 @@ struct inet_connection_sock_af_ops {
60 * @icsk_timeout: Timeout 60 * @icsk_timeout: Timeout
61 * @icsk_retransmit_timer: Resend (no ack) 61 * @icsk_retransmit_timer: Resend (no ack)
62 * @icsk_rto: Retransmit timeout 62 * @icsk_rto: Retransmit timeout
63 * @icsk_pmtu_cookie Last pmtu seen by socket
63 * @icsk_ca_ops Pluggable congestion control hook 64 * @icsk_ca_ops Pluggable congestion control hook
64 * @icsk_af_ops Operations which are AF_INET{4,6} specific 65 * @icsk_af_ops Operations which are AF_INET{4,6} specific
65 * @icsk_ca_state: Congestion control state 66 * @icsk_ca_state: Congestion control state
@@ -68,6 +69,7 @@ struct inet_connection_sock_af_ops {
68 * @icsk_backoff: Backoff 69 * @icsk_backoff: Backoff
69 * @icsk_syn_retries: Number of allowed SYN (or equivalent) retries 70 * @icsk_syn_retries: Number of allowed SYN (or equivalent) retries
70 * @icsk_probes_out: unanswered 0 window probes 71 * @icsk_probes_out: unanswered 0 window probes
72 * @icsk_ext_hdr_len: Network protocol overhead (IP/IPv6 options)
71 * @icsk_ack: Delayed ACK control data 73 * @icsk_ack: Delayed ACK control data
72 */ 74 */
73struct inet_connection_sock { 75struct inet_connection_sock {
@@ -79,15 +81,17 @@ struct inet_connection_sock {
79 struct timer_list icsk_retransmit_timer; 81 struct timer_list icsk_retransmit_timer;
80 struct timer_list icsk_delack_timer; 82 struct timer_list icsk_delack_timer;
81 __u32 icsk_rto; 83 __u32 icsk_rto;
84 __u32 icsk_pmtu_cookie;
82 struct tcp_congestion_ops *icsk_ca_ops; 85 struct tcp_congestion_ops *icsk_ca_ops;
83 struct inet_connection_sock_af_ops *icsk_af_ops; 86 struct inet_connection_sock_af_ops *icsk_af_ops;
87 unsigned int (*icsk_sync_mss)(struct sock *sk, u32 pmtu);
84 __u8 icsk_ca_state; 88 __u8 icsk_ca_state;
85 __u8 icsk_retransmits; 89 __u8 icsk_retransmits;
86 __u8 icsk_pending; 90 __u8 icsk_pending;
87 __u8 icsk_backoff; 91 __u8 icsk_backoff;
88 __u8 icsk_syn_retries; 92 __u8 icsk_syn_retries;
89 __u8 icsk_probes_out; 93 __u8 icsk_probes_out;
90 /* 2 BYTES HOLE, TRY TO PACK! */ 94 __u16 icsk_ext_hdr_len;
91 struct { 95 struct {
92 __u8 pending; /* ACK is pending */ 96 __u8 pending; /* ACK is pending */
93 __u8 quick; /* Scheduled number of quick acks */ 97 __u8 quick; /* Scheduled number of quick acks */
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 357691f6a45f..a29cb29647d0 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -76,6 +76,7 @@ struct inet_protosw {
76}; 76};
77#define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */ 77#define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */
78#define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */ 78#define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */
79#define INET_PROTOSW_ICSK 0x04 /* Is this an inet_connection_sock? */
79 80
80extern struct net_protocol *inet_protocol_base; 81extern struct net_protocol *inet_protocol_base;
81extern struct net_protocol *inet_protos[MAX_INET_PROTOS]; 82extern struct net_protocol *inet_protos[MAX_INET_PROTOS];
diff --git a/net/dccp/diag.c b/net/dccp/diag.c
index f675d8e642d3..3f78c00e3822 100644
--- a/net/dccp/diag.c
+++ b/net/dccp/diag.c
@@ -28,7 +28,7 @@ static void dccp_get_info(struct sock *sk, struct tcp_info *info)
28 info->tcpi_retransmits = icsk->icsk_retransmits; 28 info->tcpi_retransmits = icsk->icsk_retransmits;
29 info->tcpi_probes = icsk->icsk_probes_out; 29 info->tcpi_probes = icsk->icsk_probes_out;
30 info->tcpi_backoff = icsk->icsk_backoff; 30 info->tcpi_backoff = icsk->icsk_backoff;
31 info->tcpi_pmtu = dp->dccps_pmtu_cookie; 31 info->tcpi_pmtu = icsk->icsk_pmtu_cookie;
32 32
33 if (dp->dccps_options.dccpo_send_ack_vector) 33 if (dp->dccps_options.dccpo_send_ack_vector)
34 info->tcpi_options |= TCPI_OPT_SACK; 34 info->tcpi_options |= TCPI_OPT_SACK;
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 9a724ff2a622..55e921bdd131 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -311,7 +311,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
311 goto out_invalid_packet; 311 goto out_invalid_packet;
312 } 312 }
313 313
314 dccp_sync_mss(sk, dp->dccps_pmtu_cookie); 314 dccp_sync_mss(sk, icsk->icsk_pmtu_cookie);
315 315
316 /* 316 /*
317 * Step 10: Process REQUEST state (second part) 317 * Step 10: Process REQUEST state (second part)
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 671fbf3b2379..c363051a7f16 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -104,9 +104,9 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
104 inet->dport = usin->sin_port; 104 inet->dport = usin->sin_port;
105 inet->daddr = daddr; 105 inet->daddr = daddr;
106 106
107 dp->dccps_ext_header_len = 0; 107 inet_csk(sk)->icsk_ext_hdr_len = 0;
108 if (inet->opt != NULL) 108 if (inet->opt != NULL)
109 dp->dccps_ext_header_len = inet->opt->optlen; 109 inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;
110 /* 110 /*
111 * Socket identity is still unknown (sport may be zero). 111 * Socket identity is still unknown (sport may be zero).
112 * However we set state to DCCP_REQUESTING and not releasing socket 112 * However we set state to DCCP_REQUESTING and not releasing socket
@@ -191,7 +191,7 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk,
191 mtu = dst_mtu(dst); 191 mtu = dst_mtu(dst);
192 192
193 if (inet->pmtudisc != IP_PMTUDISC_DONT && 193 if (inet->pmtudisc != IP_PMTUDISC_DONT &&
194 dp->dccps_pmtu_cookie > mtu) { 194 inet_csk(sk)->icsk_pmtu_cookie > mtu) {
195 dccp_sync_mss(sk, mtu); 195 dccp_sync_mss(sk, mtu);
196 196
197 /* 197 /*
@@ -1051,6 +1051,7 @@ struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
1051int dccp_v4_init_sock(struct sock *sk) 1051int dccp_v4_init_sock(struct sock *sk)
1052{ 1052{
1053 struct dccp_sock *dp = dccp_sk(sk); 1053 struct dccp_sock *dp = dccp_sk(sk);
1054 struct inet_connection_sock *icsk = inet_csk(sk);
1054 static int dccp_ctl_socket_init = 1; 1055 static int dccp_ctl_socket_init = 1;
1055 1056
1056 dccp_options_init(&dp->dccps_options); 1057 dccp_options_init(&dp->dccps_options);
@@ -1090,10 +1091,11 @@ int dccp_v4_init_sock(struct sock *sk)
1090 dccp_ctl_socket_init = 0; 1091 dccp_ctl_socket_init = 0;
1091 1092
1092 dccp_init_xmit_timers(sk); 1093 dccp_init_xmit_timers(sk);
1093 inet_csk(sk)->icsk_rto = DCCP_TIMEOUT_INIT; 1094 icsk->icsk_rto = DCCP_TIMEOUT_INIT;
1094 sk->sk_state = DCCP_CLOSED; 1095 sk->sk_state = DCCP_CLOSED;
1095 sk->sk_write_space = dccp_write_space; 1096 sk->sk_write_space = dccp_write_space;
1096 inet_csk(sk)->icsk_af_ops = &dccp_ipv4_af_ops; 1097 icsk->icsk_af_ops = &dccp_ipv4_af_ops;
1098 icsk->icsk_sync_mss = dccp_sync_mss;
1097 dp->dccps_mss_cache = 536; 1099 dp->dccps_mss_cache = 536;
1098 dp->dccps_role = DCCP_ROLE_UNDEFINED; 1100 dp->dccps_role = DCCP_ROLE_UNDEFINED;
1099 dp->dccps_service = DCCP_SERVICE_INVALID_VALUE; 1101 dp->dccps_service = DCCP_SERVICE_INVALID_VALUE;
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 71bf04eb21e1..599b0be21515 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -88,6 +88,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
88 int addr_len) 88 int addr_len)
89{ 89{
90 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; 90 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
91 struct inet_connection_sock *icsk = inet_csk(sk);
91 struct inet_sock *inet = inet_sk(sk); 92 struct inet_sock *inet = inet_sk(sk);
92 struct ipv6_pinfo *np = inet6_sk(sk); 93 struct ipv6_pinfo *np = inet6_sk(sk);
93 struct dccp_sock *dp = dccp_sk(sk); 94 struct dccp_sock *dp = dccp_sk(sk);
@@ -158,7 +159,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
158 */ 159 */
159 160
160 if (addr_type == IPV6_ADDR_MAPPED) { 161 if (addr_type == IPV6_ADDR_MAPPED) {
161 u32 exthdrlen = dp->dccps_ext_header_len; 162 u32 exthdrlen = icsk->icsk_ext_hdr_len;
162 struct sockaddr_in sin; 163 struct sockaddr_in sin;
163 164
164 SOCK_DEBUG(sk, "connect: ipv4 mapped\n"); 165 SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
@@ -170,14 +171,14 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
170 sin.sin_port = usin->sin6_port; 171 sin.sin_port = usin->sin6_port;
171 sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; 172 sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
172 173
173 inet_csk(sk)->icsk_af_ops = &dccp_ipv6_mapped; 174 icsk->icsk_af_ops = &dccp_ipv6_mapped;
174 sk->sk_backlog_rcv = dccp_v4_do_rcv; 175 sk->sk_backlog_rcv = dccp_v4_do_rcv;
175 176
176 err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin)); 177 err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
177 178
178 if (err) { 179 if (err) {
179 dp->dccps_ext_header_len = exthdrlen; 180 icsk->icsk_ext_hdr_len = exthdrlen;
180 inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops; 181 icsk->icsk_af_ops = &dccp_ipv6_af_ops;
181 sk->sk_backlog_rcv = dccp_v6_do_rcv; 182 sk->sk_backlog_rcv = dccp_v6_do_rcv;
182 goto failure; 183 goto failure;
183 } else { 184 } else {
@@ -227,9 +228,10 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
227 228
228 ip6_dst_store(sk, dst, NULL); 229 ip6_dst_store(sk, dst, NULL);
229 230
230 dp->dccps_ext_header_len = 0; 231 icsk->icsk_ext_hdr_len = 0;
231 if (np->opt) 232 if (np->opt)
232 dp->dccps_ext_header_len = np->opt->opt_flen + np->opt->opt_nflen; 233 icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
234 np->opt->opt_nflen);
233 235
234 inet->dport = usin->sin6_port; 236 inet->dport = usin->sin6_port;
235 237
@@ -292,7 +294,6 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
292 np = inet6_sk(sk); 294 np = inet6_sk(sk);
293 295
294 if (type == ICMPV6_PKT_TOOBIG) { 296 if (type == ICMPV6_PKT_TOOBIG) {
295 struct dccp_sock *dp = dccp_sk(sk);
296 struct dst_entry *dst = NULL; 297 struct dst_entry *dst = NULL;
297 298
298 if (sock_owned_by_user(sk)) 299 if (sock_owned_by_user(sk))
@@ -332,7 +333,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
332 } else 333 } else
333 dst_hold(dst); 334 dst_hold(dst);
334 335
335 if (dp->dccps_pmtu_cookie > dst_mtu(dst)) { 336 if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) {
336 dccp_sync_mss(sk, dst_mtu(dst)); 337 dccp_sync_mss(sk, dst_mtu(dst));
337 } /* else let the usual retransmit timer handle it */ 338 } /* else let the usual retransmit timer handle it */
338 dst_release(dst); 339 dst_release(dst);
@@ -808,7 +809,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
808 worked with IPv6 icsk.icsk_af_ops. 809 worked with IPv6 icsk.icsk_af_ops.
809 Sync it now. 810 Sync it now.
810 */ 811 */
811 dccp_sync_mss(newsk, newdp->dccps_pmtu_cookie); 812 dccp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
812 813
813 return newsk; 814 return newsk;
814 } 815 }
@@ -916,10 +917,10 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
916 sock_kfree_s(sk, opt, opt->tot_len); 917 sock_kfree_s(sk, opt, opt->tot_len);
917 } 918 }
918 919
919 newdp->dccps_ext_header_len = 0; 920 inet_csk(newsk)->icsk_ext_hdr_len = 0;
920 if (newnp->opt) 921 if (newnp->opt)
921 newdp->dccps_ext_header_len = newnp->opt->opt_nflen + 922 inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
922 newnp->opt->opt_flen; 923 newnp->opt->opt_flen);
923 924
924 dccp_sync_mss(newsk, dst_mtu(dst)); 925 dccp_sync_mss(newsk, dst_mtu(dst));
925 926
@@ -1230,6 +1231,7 @@ static struct inet_protosw dccp_v6_protosw = {
1230 .prot = &dccp_v6_prot, 1231 .prot = &dccp_v6_prot,
1231 .ops = &inet6_dccp_ops, 1232 .ops = &inet6_dccp_ops,
1232 .capability = -1, 1233 .capability = -1,
1234 .flags = INET_PROTOSW_ICSK,
1233}; 1235};
1234 1236
1235static int __init dccp_v6_init(void) 1237static int __init dccp_v6_init(void)
diff --git a/net/dccp/output.c b/net/dccp/output.c
index c40f7f8a328b..95a3c2c6a3ce 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -134,12 +134,13 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
134 134
135unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu) 135unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
136{ 136{
137 struct inet_connection_sock *icsk = inet_csk(sk);
137 struct dccp_sock *dp = dccp_sk(sk); 138 struct dccp_sock *dp = dccp_sk(sk);
138 int mss_now = (pmtu - inet_csk(sk)->icsk_af_ops->net_header_len - 139 int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len -
139 sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext)); 140 sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext));
140 141
141 /* Now subtract optional transport overhead */ 142 /* Now subtract optional transport overhead */
142 mss_now -= dp->dccps_ext_header_len; 143 mss_now -= icsk->icsk_ext_hdr_len;
143 144
144 /* 145 /*
145 * FIXME: this should come from the CCID infrastructure, where, say, 146 * FIXME: this should come from the CCID infrastructure, where, say,
@@ -152,7 +153,7 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
152 mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4; 153 mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4;
153 154
154 /* And store cached results */ 155 /* And store cached results */
155 dp->dccps_pmtu_cookie = pmtu; 156 icsk->icsk_pmtu_cookie = pmtu;
156 dp->dccps_mss_cache = mss_now; 157 dp->dccps_mss_cache = mss_now;
157 158
158 return mss_now; 159 return mss_now;
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 51dfacd22a6e..40a4c6899051 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -712,7 +712,7 @@ static struct inet_protosw dccp_v4_protosw = {
712 .ops = &inet_dccp_ops, 712 .ops = &inet_dccp_ops,
713 .capability = -1, 713 .capability = -1,
714 .no_check = 0, 714 .no_check = 0,
715 .flags = 0, 715 .flags = INET_PROTOSW_ICSK,
716}; 716};
717 717
718/* 718/*
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index d368cf249000..617e858beff1 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -302,6 +302,7 @@ lookup_protocol:
302 sk->sk_reuse = 1; 302 sk->sk_reuse = 1;
303 303
304 inet = inet_sk(sk); 304 inet = inet_sk(sk);
305 inet->is_icsk = INET_PROTOSW_ICSK & answer_flags;
305 306
306 if (SOCK_RAW == sock->type) { 307 if (SOCK_RAW == sock->type) {
307 inet->num = protocol; 308 inet->num = protocol;
@@ -869,7 +870,8 @@ static struct inet_protosw inetsw_array[] =
869 .ops = &inet_stream_ops, 870 .ops = &inet_stream_ops,
870 .capability = -1, 871 .capability = -1,
871 .no_check = 0, 872 .no_check = 0,
872 .flags = INET_PROTOSW_PERMANENT, 873 .flags = INET_PROTOSW_PERMANENT |
874 INET_PROTOSW_ICSK,
873 }, 875 },
874 876
875 { 877 {
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 4f2d87257309..add019c746f8 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -29,8 +29,7 @@
29#include <net/sock.h> 29#include <net/sock.h>
30#include <net/ip.h> 30#include <net/ip.h>
31#include <net/icmp.h> 31#include <net/icmp.h>
32#include <net/tcp.h> 32#include <net/tcp_states.h>
33#include <linux/tcp.h>
34#include <linux/udp.h> 33#include <linux/udp.h>
35#include <linux/igmp.h> 34#include <linux/igmp.h>
36#include <linux/netfilter.h> 35#include <linux/netfilter.h>
@@ -427,8 +426,8 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
427 err = ip_options_get_from_user(&opt, optval, optlen); 426 err = ip_options_get_from_user(&opt, optval, optlen);
428 if (err) 427 if (err)
429 break; 428 break;
430 if (sk->sk_type == SOCK_STREAM) { 429 if (inet->is_icsk) {
431 struct tcp_sock *tp = tcp_sk(sk); 430 struct inet_connection_sock *icsk = inet_csk(sk);
432#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 431#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
433 if (sk->sk_family == PF_INET || 432 if (sk->sk_family == PF_INET ||
434 (!((1 << sk->sk_state) & 433 (!((1 << sk->sk_state) &
@@ -436,10 +435,10 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
436 inet->daddr != LOOPBACK4_IPV6)) { 435 inet->daddr != LOOPBACK4_IPV6)) {
437#endif 436#endif
438 if (inet->opt) 437 if (inet->opt)
439 tp->ext_header_len -= inet->opt->optlen; 438 icsk->icsk_ext_hdr_len -= inet->opt->optlen;
440 if (opt) 439 if (opt)
441 tp->ext_header_len += opt->optlen; 440 icsk->icsk_ext_hdr_len += opt->optlen;
442 tcp_sync_mss(sk, tp->pmtu_cookie); 441 icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
443#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 442#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
444 } 443 }
445#endif 444#endif
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index eacfe6a3442c..00aa80e93243 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1914,7 +1914,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
1914 info->tcpi_last_data_recv = jiffies_to_msecs(now - icsk->icsk_ack.lrcvtime); 1914 info->tcpi_last_data_recv = jiffies_to_msecs(now - icsk->icsk_ack.lrcvtime);
1915 info->tcpi_last_ack_recv = jiffies_to_msecs(now - tp->rcv_tstamp); 1915 info->tcpi_last_ack_recv = jiffies_to_msecs(now - tp->rcv_tstamp);
1916 1916
1917 info->tcpi_pmtu = tp->pmtu_cookie; 1917 info->tcpi_pmtu = icsk->icsk_pmtu_cookie;
1918 info->tcpi_rcv_ssthresh = tp->rcv_ssthresh; 1918 info->tcpi_rcv_ssthresh = tp->rcv_ssthresh;
1919 info->tcpi_rtt = jiffies_to_usecs(tp->srtt)>>3; 1919 info->tcpi_rtt = jiffies_to_usecs(tp->srtt)>>3;
1920 info->tcpi_rttvar = jiffies_to_usecs(tp->mdev)>>2; 1920 info->tcpi_rttvar = jiffies_to_usecs(tp->mdev)>>2;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 7de6184d4bd8..981d1203b152 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2342,7 +2342,7 @@ static int tcp_ack_update_window(struct sock *sk, struct tcp_sock *tp,
2342 2342
2343 if (nwin > tp->max_window) { 2343 if (nwin > tp->max_window) {
2344 tp->max_window = nwin; 2344 tp->max_window = nwin;
2345 tcp_sync_mss(sk, tp->pmtu_cookie); 2345 tcp_sync_mss(sk, inet_csk(sk)->icsk_pmtu_cookie);
2346 } 2346 }
2347 } 2347 }
2348 } 2348 }
@@ -3967,12 +3967,12 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
3967 struct tcphdr *th, unsigned len) 3967 struct tcphdr *th, unsigned len)
3968{ 3968{
3969 struct tcp_sock *tp = tcp_sk(sk); 3969 struct tcp_sock *tp = tcp_sk(sk);
3970 struct inet_connection_sock *icsk = inet_csk(sk);
3970 int saved_clamp = tp->rx_opt.mss_clamp; 3971 int saved_clamp = tp->rx_opt.mss_clamp;
3971 3972
3972 tcp_parse_options(skb, &tp->rx_opt, 0); 3973 tcp_parse_options(skb, &tp->rx_opt, 0);
3973 3974
3974 if (th->ack) { 3975 if (th->ack) {
3975 struct inet_connection_sock *icsk;
3976 /* rfc793: 3976 /* rfc793:
3977 * "If the state is SYN-SENT then 3977 * "If the state is SYN-SENT then
3978 * first check the ACK bit 3978 * first check the ACK bit
@@ -4061,7 +4061,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
4061 if (tp->rx_opt.sack_ok && sysctl_tcp_fack) 4061 if (tp->rx_opt.sack_ok && sysctl_tcp_fack)
4062 tp->rx_opt.sack_ok |= 2; 4062 tp->rx_opt.sack_ok |= 2;
4063 4063
4064 tcp_sync_mss(sk, tp->pmtu_cookie); 4064 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
4065 tcp_initialize_rcv_mss(sk); 4065 tcp_initialize_rcv_mss(sk);
4066 4066
4067 /* Remember, tcp_poll() does not lock socket! 4067 /* Remember, tcp_poll() does not lock socket!
@@ -4071,8 +4071,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
4071 mb(); 4071 mb();
4072 tcp_set_state(sk, TCP_ESTABLISHED); 4072 tcp_set_state(sk, TCP_ESTABLISHED);
4073 4073
4074 icsk = inet_csk(sk);
4075
4076 /* Make sure socket is routed, for correct metrics. */ 4074 /* Make sure socket is routed, for correct metrics. */
4077 icsk->icsk_af_ops->rebuild_header(sk); 4075 icsk->icsk_af_ops->rebuild_header(sk);
4078 4076
@@ -4173,7 +4171,7 @@ discard:
4173 if (tp->ecn_flags&TCP_ECN_OK) 4171 if (tp->ecn_flags&TCP_ECN_OK)
4174 sock_set_flag(sk, SOCK_NO_LARGESEND); 4172 sock_set_flag(sk, SOCK_NO_LARGESEND);
4175 4173
4176 tcp_sync_mss(sk, tp->pmtu_cookie); 4174 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
4177 tcp_initialize_rcv_mss(sk); 4175 tcp_initialize_rcv_mss(sk);
4178 4176
4179 4177
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index c2fe61becd61..9b62d80bb20f 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -220,9 +220,9 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
220 inet->dport = usin->sin_port; 220 inet->dport = usin->sin_port;
221 inet->daddr = daddr; 221 inet->daddr = daddr;
222 222
223 tp->ext_header_len = 0; 223 inet_csk(sk)->icsk_ext_hdr_len = 0;
224 if (inet->opt) 224 if (inet->opt)
225 tp->ext_header_len = inet->opt->optlen; 225 inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;
226 226
227 tp->rx_opt.mss_clamp = 536; 227 tp->rx_opt.mss_clamp = 536;
228 228
@@ -275,7 +275,6 @@ static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *iph,
275{ 275{
276 struct dst_entry *dst; 276 struct dst_entry *dst;
277 struct inet_sock *inet = inet_sk(sk); 277 struct inet_sock *inet = inet_sk(sk);
278 struct tcp_sock *tp = tcp_sk(sk);
279 278
280 /* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs 279 /* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs
281 * send out by Linux are always <576bytes so they should go through 280 * send out by Linux are always <576bytes so they should go through
@@ -304,7 +303,7 @@ static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *iph,
304 mtu = dst_mtu(dst); 303 mtu = dst_mtu(dst);
305 304
306 if (inet->pmtudisc != IP_PMTUDISC_DONT && 305 if (inet->pmtudisc != IP_PMTUDISC_DONT &&
307 tp->pmtu_cookie > mtu) { 306 inet_csk(sk)->icsk_pmtu_cookie > mtu) {
308 tcp_sync_mss(sk, mtu); 307 tcp_sync_mss(sk, mtu);
309 308
310 /* Resend the TCP packet because it's 309 /* Resend the TCP packet because it's
@@ -895,9 +894,9 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
895 ireq->opt = NULL; 894 ireq->opt = NULL;
896 newinet->mc_index = inet_iif(skb); 895 newinet->mc_index = inet_iif(skb);
897 newinet->mc_ttl = skb->nh.iph->ttl; 896 newinet->mc_ttl = skb->nh.iph->ttl;
898 newtp->ext_header_len = 0; 897 inet_csk(newsk)->icsk_ext_hdr_len = 0;
899 if (newinet->opt) 898 if (newinet->opt)
900 newtp->ext_header_len = newinet->opt->optlen; 899 inet_csk(newsk)->icsk_ext_hdr_len = newinet->opt->optlen;
901 newinet->id = newtp->write_seq ^ jiffies; 900 newinet->id = newtp->write_seq ^ jiffies;
902 901
903 tcp_sync_mss(newsk, dst_mtu(dst)); 902 tcp_sync_mss(newsk, dst_mtu(dst));
@@ -1266,6 +1265,7 @@ static int tcp_v4_init_sock(struct sock *sk)
1266 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 1265 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
1267 1266
1268 icsk->icsk_af_ops = &ipv4_specific; 1267 icsk->icsk_af_ops = &ipv4_specific;
1268 icsk->icsk_sync_mss = tcp_sync_mss;
1269 1269
1270 sk->sk_sndbuf = sysctl_tcp_wmem[1]; 1270 sk->sk_sndbuf = sysctl_tcp_wmem[1];
1271 sk->sk_rcvbuf = sysctl_tcp_rmem[1]; 1271 sk->sk_rcvbuf = sysctl_tcp_rmem[1];
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index af1946c52c37..3a0a914de917 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -621,7 +621,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
621 It is minimum of user_mss and mss received with SYN. 621 It is minimum of user_mss and mss received with SYN.
622 It also does not include TCP options. 622 It also does not include TCP options.
623 623
624 tp->pmtu_cookie is last pmtu, seen by this function. 624 inet_csk(sk)->icsk_pmtu_cookie is last pmtu, seen by this function.
625 625
626 tp->mss_cache is current effective sending mss, including 626 tp->mss_cache is current effective sending mss, including
627 all tcp options except for SACKs. It is evaluated, 627 all tcp options except for SACKs. It is evaluated,
@@ -631,17 +631,18 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
631 NOTE1. rfc1122 clearly states that advertised MSS 631 NOTE1. rfc1122 clearly states that advertised MSS
632 DOES NOT include either tcp or ip options. 632 DOES NOT include either tcp or ip options.
633 633
634 NOTE2. tp->pmtu_cookie and tp->mss_cache are READ ONLY outside 634 NOTE2. inet_csk(sk)->icsk_pmtu_cookie and tp->mss_cache
635 this function. --ANK (980731) 635 are READ ONLY outside this function. --ANK (980731)
636 */ 636 */
637 637
638unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu) 638unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
639{ 639{
640 struct tcp_sock *tp = tcp_sk(sk); 640 struct tcp_sock *tp = tcp_sk(sk);
641 struct inet_connection_sock *icsk = inet_csk(sk);
641 /* Calculate base mss without TCP options: 642 /* Calculate base mss without TCP options:
642 It is MMS_S - sizeof(tcphdr) of rfc1122 643 It is MMS_S - sizeof(tcphdr) of rfc1122
643 */ 644 */
644 int mss_now = (pmtu - inet_csk(sk)->icsk_af_ops->net_header_len - 645 int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len -
645 sizeof(struct tcphdr)); 646 sizeof(struct tcphdr));
646 647
647 /* Clamp it (mss_clamp does not include tcp options) */ 648 /* Clamp it (mss_clamp does not include tcp options) */
@@ -649,7 +650,7 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
649 mss_now = tp->rx_opt.mss_clamp; 650 mss_now = tp->rx_opt.mss_clamp;
650 651
651 /* Now subtract optional transport overhead */ 652 /* Now subtract optional transport overhead */
652 mss_now -= tp->ext_header_len; 653 mss_now -= icsk->icsk_ext_hdr_len;
653 654
654 /* Then reserve room for full set of TCP options and 8 bytes of data */ 655 /* Then reserve room for full set of TCP options and 8 bytes of data */
655 if (mss_now < 48) 656 if (mss_now < 48)
@@ -663,7 +664,7 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
663 mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len); 664 mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len);
664 665
665 /* And store cached results */ 666 /* And store cached results */
666 tp->pmtu_cookie = pmtu; 667 icsk->icsk_pmtu_cookie = pmtu;
667 tp->mss_cache = mss_now; 668 tp->mss_cache = mss_now;
668 669
669 return mss_now; 670 return mss_now;
@@ -693,7 +694,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
693 694
694 if (dst) { 695 if (dst) {
695 u32 mtu = dst_mtu(dst); 696 u32 mtu = dst_mtu(dst);
696 if (mtu != tp->pmtu_cookie) 697 if (mtu != inet_csk(sk)->icsk_pmtu_cookie)
697 mss_now = tcp_sync_mss(sk, mtu); 698 mss_now = tcp_sync_mss(sk, mtu);
698 } 699 }
699 700
@@ -706,7 +707,8 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
706 if (doing_tso) { 707 if (doing_tso) {
707 xmit_size_goal = (65535 - 708 xmit_size_goal = (65535 -
708 inet_csk(sk)->icsk_af_ops->net_header_len - 709 inet_csk(sk)->icsk_af_ops->net_header_len -
709 tp->ext_header_len - tp->tcp_header_len); 710 inet_csk(sk)->icsk_ext_hdr_len -
711 tp->tcp_header_len);
710 712
711 if (tp->max_window && 713 if (tp->max_window &&
712 (xmit_size_goal > (tp->max_window >> 1))) 714 (xmit_size_goal > (tp->max_window >> 1)))
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index bf17aab9b776..70a510ff31ee 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -167,6 +167,7 @@ lookup_protocol:
167 sk->sk_reuse = 1; 167 sk->sk_reuse = 1;
168 168
169 inet = inet_sk(sk); 169 inet = inet_sk(sk);
170 inet->is_icsk = INET_PROTOSW_ICSK & answer_flags;
170 171
171 if (SOCK_RAW == sock->type) { 172 if (SOCK_RAW == sock->type) {
172 inet->num = protocol; 173 inet->num = protocol;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index b6b63fa8454c..c63868dd2ca2 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -163,17 +163,17 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
163 sk_refcnt_debug_dec(sk); 163 sk_refcnt_debug_dec(sk);
164 164
165 if (sk->sk_protocol == IPPROTO_TCP) { 165 if (sk->sk_protocol == IPPROTO_TCP) {
166 struct tcp_sock *tp = tcp_sk(sk); 166 struct inet_connection_sock *icsk = inet_csk(sk);
167 167
168 local_bh_disable(); 168 local_bh_disable();
169 sock_prot_dec_use(sk->sk_prot); 169 sock_prot_dec_use(sk->sk_prot);
170 sock_prot_inc_use(&tcp_prot); 170 sock_prot_inc_use(&tcp_prot);
171 local_bh_enable(); 171 local_bh_enable();
172 sk->sk_prot = &tcp_prot; 172 sk->sk_prot = &tcp_prot;
173 inet_csk(sk)->icsk_af_ops = &ipv4_specific; 173 icsk->icsk_af_ops = &ipv4_specific;
174 sk->sk_socket->ops = &inet_stream_ops; 174 sk->sk_socket->ops = &inet_stream_ops;
175 sk->sk_family = PF_INET; 175 sk->sk_family = PF_INET;
176 tcp_sync_mss(sk, tp->pmtu_cookie); 176 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
177 } else { 177 } else {
178 local_bh_disable(); 178 local_bh_disable();
179 sock_prot_dec_use(sk->sk_prot); 179 sock_prot_dec_use(sk->sk_prot);
@@ -317,14 +317,15 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
317 } 317 }
318 318
319 retv = 0; 319 retv = 0;
320 if (sk->sk_type == SOCK_STREAM) { 320 if (inet_sk(sk)->is_icsk) {
321 if (opt) { 321 if (opt) {
322 struct tcp_sock *tp = tcp_sk(sk); 322 struct inet_connection_sock *icsk = inet_csk(sk);
323 if (!((1 << sk->sk_state) & 323 if (!((1 << sk->sk_state) &
324 (TCPF_LISTEN | TCPF_CLOSE)) 324 (TCPF_LISTEN | TCPF_CLOSE))
325 && inet_sk(sk)->daddr != LOOPBACK4_IPV6) { 325 && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
326 tp->ext_header_len = opt->opt_flen + opt->opt_nflen; 326 icsk->icsk_ext_hdr_len =
327 tcp_sync_mss(sk, tp->pmtu_cookie); 327 opt->opt_flen + opt->opt_nflen;
328 icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
328 } 329 }
329 } 330 }
330 opt = xchg(&np->opt, opt); 331 opt = xchg(&np->opt, opt);
@@ -380,14 +381,15 @@ sticky_done:
380 goto done; 381 goto done;
381update: 382update:
382 retv = 0; 383 retv = 0;
383 if (sk->sk_type == SOCK_STREAM) { 384 if (inet_sk(sk)->is_icsk) {
384 if (opt) { 385 if (opt) {
385 struct tcp_sock *tp = tcp_sk(sk); 386 struct inet_connection_sock *icsk = inet_csk(sk);
386 if (!((1 << sk->sk_state) & 387 if (!((1 << sk->sk_state) &
387 (TCPF_LISTEN | TCPF_CLOSE)) 388 (TCPF_LISTEN | TCPF_CLOSE))
388 && inet_sk(sk)->daddr != LOOPBACK4_IPV6) { 389 && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
389 tp->ext_header_len = opt->opt_flen + opt->opt_nflen; 390 icsk->icsk_ext_hdr_len =
390 tcp_sync_mss(sk, tp->pmtu_cookie); 391 opt->opt_flen + opt->opt_nflen;
392 icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
391 } 393 }
392 } 394 }
393 opt = xchg(&np->opt, opt); 395 opt = xchg(&np->opt, opt);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index a682eb9093e1..2947bc56d8a0 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -123,7 +123,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
123 int addr_len) 123 int addr_len)
124{ 124{
125 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; 125 struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
126 struct inet_sock *inet = inet_sk(sk); 126 struct inet_sock *inet = inet_sk(sk);
127 struct inet_connection_sock *icsk = inet_csk(sk);
127 struct ipv6_pinfo *np = inet6_sk(sk); 128 struct ipv6_pinfo *np = inet6_sk(sk);
128 struct tcp_sock *tp = tcp_sk(sk); 129 struct tcp_sock *tp = tcp_sk(sk);
129 struct in6_addr *saddr = NULL, *final_p = NULL, final; 130 struct in6_addr *saddr = NULL, *final_p = NULL, final;
@@ -198,7 +199,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
198 */ 199 */
199 200
200 if (addr_type == IPV6_ADDR_MAPPED) { 201 if (addr_type == IPV6_ADDR_MAPPED) {
201 u32 exthdrlen = tp->ext_header_len; 202 u32 exthdrlen = icsk->icsk_ext_hdr_len;
202 struct sockaddr_in sin; 203 struct sockaddr_in sin;
203 204
204 SOCK_DEBUG(sk, "connect: ipv4 mapped\n"); 205 SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
@@ -210,14 +211,14 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
210 sin.sin_port = usin->sin6_port; 211 sin.sin_port = usin->sin6_port;
211 sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; 212 sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
212 213
213 inet_csk(sk)->icsk_af_ops = &ipv6_mapped; 214 icsk->icsk_af_ops = &ipv6_mapped;
214 sk->sk_backlog_rcv = tcp_v4_do_rcv; 215 sk->sk_backlog_rcv = tcp_v4_do_rcv;
215 216
216 err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin)); 217 err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
217 218
218 if (err) { 219 if (err) {
219 tp->ext_header_len = exthdrlen; 220 icsk->icsk_ext_hdr_len = exthdrlen;
220 inet_csk(sk)->icsk_af_ops = &ipv6_specific; 221 icsk->icsk_af_ops = &ipv6_specific;
221 sk->sk_backlog_rcv = tcp_v6_do_rcv; 222 sk->sk_backlog_rcv = tcp_v6_do_rcv;
222 goto failure; 223 goto failure;
223 } else { 224 } else {
@@ -270,9 +271,10 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
270 sk->sk_route_caps = dst->dev->features & 271 sk->sk_route_caps = dst->dev->features &
271 ~(NETIF_F_IP_CSUM | NETIF_F_TSO); 272 ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
272 273
273 tp->ext_header_len = 0; 274 icsk->icsk_ext_hdr_len = 0;
274 if (np->opt) 275 if (np->opt)
275 tp->ext_header_len = np->opt->opt_flen + np->opt->opt_nflen; 276 icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
277 np->opt->opt_nflen);
276 278
277 tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 279 tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
278 280
@@ -385,7 +387,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
385 } else 387 } else
386 dst_hold(dst); 388 dst_hold(dst);
387 389
388 if (tp->pmtu_cookie > dst_mtu(dst)) { 390 if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) {
389 tcp_sync_mss(sk, dst_mtu(dst)); 391 tcp_sync_mss(sk, dst_mtu(dst));
390 tcp_simple_retransmit(sk); 392 tcp_simple_retransmit(sk);
391 } /* else let the usual retransmit timer handle it */ 393 } /* else let the usual retransmit timer handle it */
@@ -869,7 +871,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
869 worked with IPv6 icsk.icsk_af_ops. 871 worked with IPv6 icsk.icsk_af_ops.
870 Sync it now. 872 Sync it now.
871 */ 873 */
872 tcp_sync_mss(newsk, newtp->pmtu_cookie); 874 tcp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
873 875
874 return newsk; 876 return newsk;
875 } 877 }
@@ -976,10 +978,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
976 sock_kfree_s(sk, opt, opt->tot_len); 978 sock_kfree_s(sk, opt, opt->tot_len);
977 } 979 }
978 980
979 newtp->ext_header_len = 0; 981 inet_csk(newsk)->icsk_ext_hdr_len = 0;
980 if (newnp->opt) 982 if (newnp->opt)
981 newtp->ext_header_len = newnp->opt->opt_nflen + 983 inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
982 newnp->opt->opt_flen; 984 newnp->opt->opt_flen);
983 985
984 tcp_sync_mss(newsk, dst_mtu(dst)); 986 tcp_sync_mss(newsk, dst_mtu(dst));
985 newtp->advmss = dst_metric(dst, RTAX_ADVMSS); 987 newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
@@ -1361,6 +1363,7 @@ static int tcp_v6_init_sock(struct sock *sk)
1361 1363
1362 icsk->icsk_af_ops = &ipv6_specific; 1364 icsk->icsk_af_ops = &ipv6_specific;
1363 icsk->icsk_ca_ops = &tcp_init_congestion_ops; 1365 icsk->icsk_ca_ops = &tcp_init_congestion_ops;
1366 icsk->icsk_sync_mss = tcp_sync_mss;
1364 sk->sk_write_space = sk_stream_write_space; 1367 sk->sk_write_space = sk_stream_write_space;
1365 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 1368 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
1366 1369
@@ -1591,7 +1594,8 @@ static struct inet_protosw tcpv6_protosw = {
1591 .ops = &inet6_stream_ops, 1594 .ops = &inet6_stream_ops,
1592 .capability = -1, 1595 .capability = -1,
1593 .no_check = 0, 1596 .no_check = 0,
1594 .flags = INET_PROTOSW_PERMANENT, 1597 .flags = INET_PROTOSW_PERMANENT |
1598 INET_PROTOSW_ICSK,
1595}; 1599};
1596 1600
1597void __init tcpv6_init(void) 1601void __init tcpv6_init(void)