aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorGilad Ben-Yossef <gilad@codefidence.com>2009-10-28 00:15:22 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-29 04:28:41 -0400
commit022c3f7d82f0f1c68018696f2f027b87b9bb45c2 (patch)
treeca46c372d815e46f488ec348ae427d34d1f6079e /net
parentf55017a93f1a74d50244b1254b9a2bd7ac9bbf7d (diff)
Allow tcp_parse_options to consult dst entry
We need tcp_parse_options to be aware of dst_entry to take into account per dst_entry TCP options settings Signed-off-by: Gilad Ben-Yossef <gilad@codefidence.com> Sigend-off-by: Ori Finkelman <ori@comsleep.com> Sigend-off-by: Yony Amit <yony@comsleep.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/syncookies.c27
-rw-r--r--net/ipv4/tcp_input.c9
-rw-r--r--net/ipv4/tcp_ipv4.c21
-rw-r--r--net/ipv4/tcp_minisocks.c7
-rw-r--r--net/ipv6/syncookies.c28
-rw-r--r--net/ipv6/tcp_ipv6.c3
6 files changed, 54 insertions, 41 deletions
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 5ec678ad70ef..3146cc401748 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -276,13 +276,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
276 276
277 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV); 277 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV);
278 278
279 /* check for timestamp cookie support */
280 memset(&tcp_opt, 0, sizeof(tcp_opt));
281 tcp_parse_options(skb, &tcp_opt, 0);
282
283 if (tcp_opt.saw_tstamp)
284 cookie_check_timestamp(&tcp_opt);
285
286 ret = NULL; 279 ret = NULL;
287 req = inet_reqsk_alloc(&tcp_request_sock_ops); /* for safety */ 280 req = inet_reqsk_alloc(&tcp_request_sock_ops); /* for safety */
288 if (!req) 281 if (!req)
@@ -298,12 +291,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
298 ireq->loc_addr = ip_hdr(skb)->daddr; 291 ireq->loc_addr = ip_hdr(skb)->daddr;
299 ireq->rmt_addr = ip_hdr(skb)->saddr; 292 ireq->rmt_addr = ip_hdr(skb)->saddr;
300 ireq->ecn_ok = 0; 293 ireq->ecn_ok = 0;
301 ireq->snd_wscale = tcp_opt.snd_wscale;
302 ireq->rcv_wscale = tcp_opt.rcv_wscale;
303 ireq->sack_ok = tcp_opt.sack_ok;
304 ireq->wscale_ok = tcp_opt.wscale_ok;
305 ireq->tstamp_ok = tcp_opt.saw_tstamp;
306 req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
307 294
308 /* We throwed the options of the initial SYN away, so we hope 295 /* We throwed the options of the initial SYN away, so we hope
309 * the ACK carries the same options again (see RFC1122 4.2.3.8) 296 * the ACK carries the same options again (see RFC1122 4.2.3.8)
@@ -352,6 +339,20 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
352 } 339 }
353 } 340 }
354 341
342 /* check for timestamp cookie support */
343 memset(&tcp_opt, 0, sizeof(tcp_opt));
344 tcp_parse_options(skb, &tcp_opt, 0, &rt->u.dst);
345
346 if (tcp_opt.saw_tstamp)
347 cookie_check_timestamp(&tcp_opt);
348
349 ireq->snd_wscale = tcp_opt.snd_wscale;
350 ireq->rcv_wscale = tcp_opt.rcv_wscale;
351 ireq->sack_ok = tcp_opt.sack_ok;
352 ireq->wscale_ok = tcp_opt.wscale_ok;
353 ireq->tstamp_ok = tcp_opt.saw_tstamp;
354 req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
355
355 /* Try to redo what tcp_v4_send_synack did. */ 356 /* Try to redo what tcp_v4_send_synack did. */
356 req->window_clamp = tp->window_clamp ? :dst_metric(&rt->u.dst, RTAX_WINDOW); 357 req->window_clamp = tp->window_clamp ? :dst_metric(&rt->u.dst, RTAX_WINDOW);
357 358
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index a0c3700bae3a..c7625005486d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3698,12 +3698,14 @@ old_ack:
3698 * the fast version below fails. 3698 * the fast version below fails.
3699 */ 3699 */
3700void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, 3700void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
3701 int estab) 3701 int estab, struct dst_entry *dst)
3702{ 3702{
3703 unsigned char *ptr; 3703 unsigned char *ptr;
3704 struct tcphdr *th = tcp_hdr(skb); 3704 struct tcphdr *th = tcp_hdr(skb);
3705 int length = (th->doff * 4) - sizeof(struct tcphdr); 3705 int length = (th->doff * 4) - sizeof(struct tcphdr);
3706 3706
3707 BUG_ON(!estab && !dst);
3708
3707 ptr = (unsigned char *)(th + 1); 3709 ptr = (unsigned char *)(th + 1);
3708 opt_rx->saw_tstamp = 0; 3710 opt_rx->saw_tstamp = 0;
3709 3711
@@ -3820,7 +3822,7 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
3820 if (tcp_parse_aligned_timestamp(tp, th)) 3822 if (tcp_parse_aligned_timestamp(tp, th))
3821 return 1; 3823 return 1;
3822 } 3824 }
3823 tcp_parse_options(skb, &tp->rx_opt, 1); 3825 tcp_parse_options(skb, &tp->rx_opt, 1, NULL);
3824 return 1; 3826 return 1;
3825} 3827}
3826 3828
@@ -5364,8 +5366,9 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
5364 struct tcp_sock *tp = tcp_sk(sk); 5366 struct tcp_sock *tp = tcp_sk(sk);
5365 struct inet_connection_sock *icsk = inet_csk(sk); 5367 struct inet_connection_sock *icsk = inet_csk(sk);
5366 int saved_clamp = tp->rx_opt.mss_clamp; 5368 int saved_clamp = tp->rx_opt.mss_clamp;
5369 struct dst_entry *dst = __sk_dst_get(sk);
5367 5370
5368 tcp_parse_options(skb, &tp->rx_opt, 0); 5371 tcp_parse_options(skb, &tp->rx_opt, 0, dst);
5369 5372
5370 if (th->ack) { 5373 if (th->ack) {
5371 /* rfc793: 5374 /* rfc793:
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index a4a3390a5287..657ae334f125 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1257,11 +1257,21 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1257 tcp_rsk(req)->af_specific = &tcp_request_sock_ipv4_ops; 1257 tcp_rsk(req)->af_specific = &tcp_request_sock_ipv4_ops;
1258#endif 1258#endif
1259 1259
1260 ireq = inet_rsk(req);
1261 ireq->loc_addr = daddr;
1262 ireq->rmt_addr = saddr;
1263 ireq->no_srccheck = inet_sk(sk)->transparent;
1264 ireq->opt = tcp_v4_save_options(sk, skb);
1265
1266 dst = inet_csk_route_req(sk, req);
1267 if(!dst)
1268 goto drop_and_free;
1269
1260 tcp_clear_options(&tmp_opt); 1270 tcp_clear_options(&tmp_opt);
1261 tmp_opt.mss_clamp = 536; 1271 tmp_opt.mss_clamp = 536;
1262 tmp_opt.user_mss = tcp_sk(sk)->rx_opt.user_mss; 1272 tmp_opt.user_mss = tcp_sk(sk)->rx_opt.user_mss;
1263 1273
1264 tcp_parse_options(skb, &tmp_opt, 0); 1274 tcp_parse_options(skb, &tmp_opt, 0, dst);
1265 1275
1266 if (want_cookie && !tmp_opt.saw_tstamp) 1276 if (want_cookie && !tmp_opt.saw_tstamp)
1267 tcp_clear_options(&tmp_opt); 1277 tcp_clear_options(&tmp_opt);
@@ -1270,14 +1280,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1270 1280
1271 tcp_openreq_init(req, &tmp_opt, skb); 1281 tcp_openreq_init(req, &tmp_opt, skb);
1272 1282
1273 ireq = inet_rsk(req);
1274 ireq->loc_addr = daddr;
1275 ireq->rmt_addr = saddr;
1276 ireq->no_srccheck = inet_sk(sk)->transparent;
1277 ireq->opt = tcp_v4_save_options(sk, skb);
1278
1279 if (security_inet_conn_request(sk, skb, req)) 1283 if (security_inet_conn_request(sk, skb, req))
1280 goto drop_and_free; 1284 goto drop_and_release;
1281 1285
1282 if (!want_cookie) 1286 if (!want_cookie)
1283 TCP_ECN_create_request(req, tcp_hdr(skb)); 1287 TCP_ECN_create_request(req, tcp_hdr(skb));
@@ -1302,7 +1306,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1302 */ 1306 */
1303 if (tmp_opt.saw_tstamp && 1307 if (tmp_opt.saw_tstamp &&
1304 tcp_death_row.sysctl_tw_recycle && 1308 tcp_death_row.sysctl_tw_recycle &&
1305 (dst = inet_csk_route_req(sk, req)) != NULL &&
1306 (peer = rt_get_peer((struct rtable *)dst)) != NULL && 1309 (peer = rt_get_peer((struct rtable *)dst)) != NULL &&
1307 peer->v4daddr == saddr) { 1310 peer->v4daddr == saddr) {
1308 if (get_seconds() < peer->tcp_ts_stamp + TCP_PAWS_MSL && 1311 if (get_seconds() < peer->tcp_ts_stamp + TCP_PAWS_MSL &&
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 015e7c67dc88..463d51b53d37 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -102,7 +102,7 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,
102 102
103 if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { 103 if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) {
104 tmp_opt.tstamp_ok = 1; 104 tmp_opt.tstamp_ok = 1;
105 tcp_parse_options(skb, &tmp_opt, 1); 105 tcp_parse_options(skb, &tmp_opt, 1, NULL);
106 106
107 if (tmp_opt.saw_tstamp) { 107 if (tmp_opt.saw_tstamp) {
108 tmp_opt.ts_recent = tcptw->tw_ts_recent; 108 tmp_opt.ts_recent = tcptw->tw_ts_recent;
@@ -500,10 +500,11 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
500 int paws_reject = 0; 500 int paws_reject = 0;
501 struct tcp_options_received tmp_opt; 501 struct tcp_options_received tmp_opt;
502 struct sock *child; 502 struct sock *child;
503 struct dst_entry *dst = inet_csk_route_req(sk, req);
503 504
504 tmp_opt.saw_tstamp = 0; 505 tmp_opt.saw_tstamp = 0;
505 if (th->doff > (sizeof(struct tcphdr)>>2)) { 506 if (th->doff > (sizeof(struct tcphdr)>>2)) {
506 tcp_parse_options(skb, &tmp_opt, 0); 507 tcp_parse_options(skb, &tmp_opt, 0, dst);
507 508
508 if (tmp_opt.saw_tstamp) { 509 if (tmp_opt.saw_tstamp) {
509 tmp_opt.ts_recent = req->ts_recent; 510 tmp_opt.ts_recent = req->ts_recent;
@@ -516,6 +517,8 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
516 } 517 }
517 } 518 }
518 519
520 dst_release(dst);
521
519 /* Check for pure retransmitted SYN. */ 522 /* Check for pure retransmitted SYN. */
520 if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn && 523 if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn &&
521 flg == TCP_FLAG_SYN && 524 flg == TCP_FLAG_SYN &&
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index c46da533888a..612fc53e0bb9 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -184,13 +184,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
184 184
185 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV); 185 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV);
186 186
187 /* check for timestamp cookie support */
188 memset(&tcp_opt, 0, sizeof(tcp_opt));
189 tcp_parse_options(skb, &tcp_opt, 0);
190
191 if (tcp_opt.saw_tstamp)
192 cookie_check_timestamp(&tcp_opt);
193
194 ret = NULL; 187 ret = NULL;
195 req = inet6_reqsk_alloc(&tcp6_request_sock_ops); 188 req = inet6_reqsk_alloc(&tcp6_request_sock_ops);
196 if (!req) 189 if (!req)
@@ -224,12 +217,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
224 req->expires = 0UL; 217 req->expires = 0UL;
225 req->retrans = 0; 218 req->retrans = 0;
226 ireq->ecn_ok = 0; 219 ireq->ecn_ok = 0;
227 ireq->snd_wscale = tcp_opt.snd_wscale;
228 ireq->rcv_wscale = tcp_opt.rcv_wscale;
229 ireq->sack_ok = tcp_opt.sack_ok;
230 ireq->wscale_ok = tcp_opt.wscale_ok;
231 ireq->tstamp_ok = tcp_opt.saw_tstamp;
232 req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
233 treq->rcv_isn = ntohl(th->seq) - 1; 220 treq->rcv_isn = ntohl(th->seq) - 1;
234 treq->snt_isn = cookie; 221 treq->snt_isn = cookie;
235 222
@@ -265,6 +252,21 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
265 goto out_free; 252 goto out_free;
266 } 253 }
267 254
255 /* check for timestamp cookie support */
256 memset(&tcp_opt, 0, sizeof(tcp_opt));
257 tcp_parse_options(skb, &tcp_opt, 0, dst);
258
259 if (tcp_opt.saw_tstamp)
260 cookie_check_timestamp(&tcp_opt);
261
262 req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
263
264 ireq->snd_wscale = tcp_opt.snd_wscale;
265 ireq->rcv_wscale = tcp_opt.rcv_wscale;
266 ireq->sack_ok = tcp_opt.sack_ok;
267 ireq->wscale_ok = tcp_opt.wscale_ok;
268 ireq->tstamp_ok = tcp_opt.saw_tstamp;
269
268 req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); 270 req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
269 tcp_select_initial_window(tcp_full_space(sk), req->mss, 271 tcp_select_initial_window(tcp_full_space(sk), req->mss,
270 &req->rcv_wnd, &req->window_clamp, 272 &req->rcv_wnd, &req->window_clamp,
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index c54ec3615ded..34925f089e07 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1167,6 +1167,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1167 struct tcp_sock *tp = tcp_sk(sk); 1167 struct tcp_sock *tp = tcp_sk(sk);
1168 struct request_sock *req = NULL; 1168 struct request_sock *req = NULL;
1169 __u32 isn = TCP_SKB_CB(skb)->when; 1169 __u32 isn = TCP_SKB_CB(skb)->when;
1170 struct dst_entry *dst = __sk_dst_get(sk);
1170#ifdef CONFIG_SYN_COOKIES 1171#ifdef CONFIG_SYN_COOKIES
1171 int want_cookie = 0; 1172 int want_cookie = 0;
1172#else 1173#else
@@ -1205,7 +1206,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1205 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 1206 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
1206 tmp_opt.user_mss = tp->rx_opt.user_mss; 1207 tmp_opt.user_mss = tp->rx_opt.user_mss;
1207 1208
1208 tcp_parse_options(skb, &tmp_opt, 0); 1209 tcp_parse_options(skb, &tmp_opt, 0, dst);
1209 1210
1210 if (want_cookie && !tmp_opt.saw_tstamp) 1211 if (want_cookie && !tmp_opt.saw_tstamp)
1211 tcp_clear_options(&tmp_opt); 1212 tcp_clear_options(&tmp_opt);