aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Allen Simpson <william.allen.simpson@gmail.com>2009-12-02 13:07:39 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-03 01:07:23 -0500
commite6b4d11367519bc71729c09d05a126b133c755be (patch)
treeb5d99b115a6ca9564d367b243a826d8b09da237e
parente00484023ebe94dce03fdd1270edf3e191c2bc79 (diff)
TCPCT part 1a: add request_values parameter for sending SYNACK
Add optional function parameters associated with sending SYNACK. These parameters are not needed after sending SYNACK, and are not used for retransmission. Avoids extending struct tcp_request_sock, and avoids allocating kernel memory. Also affects DCCP as it uses common struct request_sock_ops, but this parameter is currently reserved for future use. Signed-off-by: William.Allen.Simpson@gmail.com Acked-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/request_sock.h8
-rw-r--r--include/net/tcp.h3
-rw-r--r--net/dccp/ipv4.c5
-rw-r--r--net/dccp/ipv6.c5
-rw-r--r--net/dccp/minisocks.c2
-rw-r--r--net/ipv4/inet_connection_sock.c2
-rw-r--r--net/ipv4/tcp_ipv4.c18
-rw-r--r--net/ipv4/tcp_minisocks.c2
-rw-r--r--net/ipv4/tcp_output.c3
-rw-r--r--net/ipv6/tcp_ipv6.c27
10 files changed, 42 insertions, 33 deletions
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index c7190846e128..c9b50ebd9ce9 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -27,13 +27,19 @@ struct sk_buff;
27struct dst_entry; 27struct dst_entry;
28struct proto; 28struct proto;
29 29
30/* empty to "strongly type" an otherwise void parameter.
31 */
32struct request_values {
33};
34
30struct request_sock_ops { 35struct request_sock_ops {
31 int family; 36 int family;
32 int obj_size; 37 int obj_size;
33 struct kmem_cache *slab; 38 struct kmem_cache *slab;
34 char *slab_name; 39 char *slab_name;
35 int (*rtx_syn_ack)(struct sock *sk, 40 int (*rtx_syn_ack)(struct sock *sk,
36 struct request_sock *req); 41 struct request_sock *req,
42 struct request_values *rvp);
37 void (*send_ack)(struct sock *sk, struct sk_buff *skb, 43 void (*send_ack)(struct sock *sk, struct sk_buff *skb,
38 struct request_sock *req); 44 struct request_sock *req);
39 void (*send_reset)(struct sock *sk, 45 void (*send_reset)(struct sock *sk,
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 325bfcf5c934..ec183fda05d0 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -440,7 +440,8 @@ extern int tcp_connect(struct sock *sk);
440 440
441extern struct sk_buff * tcp_make_synack(struct sock *sk, 441extern struct sk_buff * tcp_make_synack(struct sock *sk,
442 struct dst_entry *dst, 442 struct dst_entry *dst,
443 struct request_sock *req); 443 struct request_sock *req,
444 struct request_values *rvp);
444 445
445extern int tcp_disconnect(struct sock *sk, int flags); 446extern int tcp_disconnect(struct sock *sk, int flags);
446 447
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 2423a0866733..efbcfdc12796 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -477,7 +477,8 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
477 return &rt->u.dst; 477 return &rt->u.dst;
478} 478}
479 479
480static int dccp_v4_send_response(struct sock *sk, struct request_sock *req) 480static int dccp_v4_send_response(struct sock *sk, struct request_sock *req,
481 struct request_values *rv_unused)
481{ 482{
482 int err = -1; 483 int err = -1;
483 struct sk_buff *skb; 484 struct sk_buff *skb;
@@ -626,7 +627,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
626 dreq->dreq_iss = dccp_v4_init_sequence(skb); 627 dreq->dreq_iss = dccp_v4_init_sequence(skb);
627 dreq->dreq_service = service; 628 dreq->dreq_service = service;
628 629
629 if (dccp_v4_send_response(sk, req)) 630 if (dccp_v4_send_response(sk, req, NULL))
630 goto drop_and_free; 631 goto drop_and_free;
631 632
632 inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); 633 inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 50ea91a77705..6574215a1f51 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -241,7 +241,8 @@ out:
241} 241}
242 242
243 243
244static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) 244static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
245 struct request_values *rv_unused)
245{ 246{
246 struct inet6_request_sock *ireq6 = inet6_rsk(req); 247 struct inet6_request_sock *ireq6 = inet6_rsk(req);
247 struct ipv6_pinfo *np = inet6_sk(sk); 248 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -468,7 +469,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
468 dreq->dreq_iss = dccp_v6_init_sequence(skb); 469 dreq->dreq_iss = dccp_v6_init_sequence(skb);
469 dreq->dreq_service = service; 470 dreq->dreq_service = service;
470 471
471 if (dccp_v6_send_response(sk, req)) 472 if (dccp_v6_send_response(sk, req, NULL))
472 goto drop_and_free; 473 goto drop_and_free;
473 474
474 inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); 475 inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index 5ca49cec95f5..af226a063141 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -184,7 +184,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
184 * counter (backoff, monitored by dccp_response_timer). 184 * counter (backoff, monitored by dccp_response_timer).
185 */ 185 */
186 req->retrans++; 186 req->retrans++;
187 req->rsk_ops->rtx_syn_ack(sk, req); 187 req->rsk_ops->rtx_syn_ack(sk, req, NULL);
188 } 188 }
189 /* Network Duplicate, discard packet */ 189 /* Network Duplicate, discard packet */
190 return NULL; 190 return NULL;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 9b35c56d1023..ee16475f8fc3 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -531,7 +531,7 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
531 &expire, &resend); 531 &expire, &resend);
532 if (!expire && 532 if (!expire &&
533 (!resend || 533 (!resend ||
534 !req->rsk_ops->rtx_syn_ack(parent, req) || 534 !req->rsk_ops->rtx_syn_ack(parent, req, NULL) ||
535 inet_rsk(req)->acked)) { 535 inet_rsk(req)->acked)) {
536 unsigned long timeo; 536 unsigned long timeo;
537 537
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index df18ce04f41e..649a36d99c73 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -742,8 +742,9 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
742 * This still operates on a request_sock only, not on a big 742 * This still operates on a request_sock only, not on a big
743 * socket. 743 * socket.
744 */ 744 */
745static int __tcp_v4_send_synack(struct sock *sk, struct request_sock *req, 745static int __tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst,
746 struct dst_entry *dst) 746 struct request_sock *req,
747 struct request_values *rvp)
747{ 748{
748 const struct inet_request_sock *ireq = inet_rsk(req); 749 const struct inet_request_sock *ireq = inet_rsk(req);
749 int err = -1; 750 int err = -1;
@@ -753,7 +754,7 @@ static int __tcp_v4_send_synack(struct sock *sk, struct request_sock *req,
753 if (!dst && (dst = inet_csk_route_req(sk, req)) == NULL) 754 if (!dst && (dst = inet_csk_route_req(sk, req)) == NULL)
754 return -1; 755 return -1;
755 756
756 skb = tcp_make_synack(sk, dst, req); 757 skb = tcp_make_synack(sk, dst, req, rvp);
757 758
758 if (skb) { 759 if (skb) {
759 struct tcphdr *th = tcp_hdr(skb); 760 struct tcphdr *th = tcp_hdr(skb);
@@ -774,9 +775,10 @@ static int __tcp_v4_send_synack(struct sock *sk, struct request_sock *req,
774 return err; 775 return err;
775} 776}
776 777
777static int tcp_v4_send_synack(struct sock *sk, struct request_sock *req) 778static int tcp_v4_send_synack(struct sock *sk, struct request_sock *req,
779 struct request_values *rvp)
778{ 780{
779 return __tcp_v4_send_synack(sk, req, NULL); 781 return __tcp_v4_send_synack(sk, NULL, req, rvp);
780} 782}
781 783
782/* 784/*
@@ -1211,13 +1213,13 @@ static struct timewait_sock_ops tcp_timewait_sock_ops = {
1211 1213
1212int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) 1214int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1213{ 1215{
1214 struct inet_request_sock *ireq;
1215 struct tcp_options_received tmp_opt; 1216 struct tcp_options_received tmp_opt;
1216 struct request_sock *req; 1217 struct request_sock *req;
1218 struct inet_request_sock *ireq;
1219 struct dst_entry *dst = NULL;
1217 __be32 saddr = ip_hdr(skb)->saddr; 1220 __be32 saddr = ip_hdr(skb)->saddr;
1218 __be32 daddr = ip_hdr(skb)->daddr; 1221 __be32 daddr = ip_hdr(skb)->daddr;
1219 __u32 isn = TCP_SKB_CB(skb)->when; 1222 __u32 isn = TCP_SKB_CB(skb)->when;
1220 struct dst_entry *dst = NULL;
1221#ifdef CONFIG_SYN_COOKIES 1223#ifdef CONFIG_SYN_COOKIES
1222 int want_cookie = 0; 1224 int want_cookie = 0;
1223#else 1225#else
@@ -1337,7 +1339,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1337 } 1339 }
1338 tcp_rsk(req)->snt_isn = isn; 1340 tcp_rsk(req)->snt_isn = isn;
1339 1341
1340 if (__tcp_v4_send_synack(sk, req, dst) || want_cookie) 1342 if (__tcp_v4_send_synack(sk, dst, req, NULL) || want_cookie)
1341 goto drop_and_free; 1343 goto drop_and_free;
1342 1344
1343 inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); 1345 inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index ab32c181f749..d3f6bbfc76f0 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -531,7 +531,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
531 * Enforce "SYN-ACK" according to figure 8, figure 6 531 * Enforce "SYN-ACK" according to figure 8, figure 6
532 * of RFC793, fixed by RFC1122. 532 * of RFC793, fixed by RFC1122.
533 */ 533 */
534 req->rsk_ops->rtx_syn_ack(sk, req); 534 req->rsk_ops->rtx_syn_ack(sk, req, NULL);
535 return NULL; 535 return NULL;
536 } 536 }
537 537
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 875bc6dcd920..b8b25049f257 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2224,7 +2224,8 @@ int tcp_send_synack(struct sock *sk)
2224 2224
2225/* Prepare a SYN-ACK. */ 2225/* Prepare a SYN-ACK. */
2226struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, 2226struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2227 struct request_sock *req) 2227 struct request_sock *req,
2228 struct request_values *rvp)
2228{ 2229{
2229 struct inet_request_sock *ireq = inet_rsk(req); 2230 struct inet_request_sock *ireq = inet_rsk(req);
2230 struct tcp_sock *tp = tcp_sk(sk); 2231 struct tcp_sock *tp = tcp_sk(sk);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index de709091b26d..da6e24416d75 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -461,7 +461,8 @@ out:
461} 461}
462 462
463 463
464static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req) 464static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
465 struct request_values *rvp)
465{ 466{
466 struct inet6_request_sock *treq = inet6_rsk(req); 467 struct inet6_request_sock *treq = inet6_rsk(req);
467 struct ipv6_pinfo *np = inet6_sk(sk); 468 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -499,7 +500,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
499 if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) 500 if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
500 goto done; 501 goto done;
501 502
502 skb = tcp_make_synack(sk, dst, req); 503 skb = tcp_make_synack(sk, dst, req, rvp);
503 if (skb) { 504 if (skb) {
504 struct tcphdr *th = tcp_hdr(skb); 505 struct tcphdr *th = tcp_hdr(skb);
505 506
@@ -1161,13 +1162,13 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
1161 */ 1162 */
1162static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) 1163static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1163{ 1164{
1165 struct tcp_options_received tmp_opt;
1166 struct request_sock *req;
1164 struct inet6_request_sock *treq; 1167 struct inet6_request_sock *treq;
1165 struct ipv6_pinfo *np = inet6_sk(sk); 1168 struct ipv6_pinfo *np = inet6_sk(sk);
1166 struct tcp_options_received tmp_opt;
1167 struct tcp_sock *tp = tcp_sk(sk); 1169 struct tcp_sock *tp = tcp_sk(sk);
1168 struct request_sock *req = NULL;
1169 __u32 isn = TCP_SKB_CB(skb)->when;
1170 struct dst_entry *dst = __sk_dst_get(sk); 1170 struct dst_entry *dst = __sk_dst_get(sk);
1171 __u32 isn = TCP_SKB_CB(skb)->when;
1171#ifdef CONFIG_SYN_COOKIES 1172#ifdef CONFIG_SYN_COOKIES
1172 int want_cookie = 0; 1173 int want_cookie = 0;
1173#else 1174#else
@@ -1239,23 +1240,19 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
1239 1240
1240 isn = tcp_v6_init_sequence(skb); 1241 isn = tcp_v6_init_sequence(skb);
1241 } 1242 }
1242
1243 tcp_rsk(req)->snt_isn = isn; 1243 tcp_rsk(req)->snt_isn = isn;
1244 1244
1245 security_inet_conn_request(sk, skb, req); 1245 security_inet_conn_request(sk, skb, req);
1246 1246
1247 if (tcp_v6_send_synack(sk, req)) 1247 if (tcp_v6_send_synack(sk, req, NULL) || want_cookie)
1248 goto drop; 1248 goto drop_and_free;
1249 1249
1250 if (!want_cookie) { 1250 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
1251 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); 1251 return 0;
1252 return 0;
1253 }
1254 1252
1253drop_and_free:
1254 reqsk_free(req);
1255drop: 1255drop:
1256 if (req)
1257 reqsk_free(req);
1258
1259 return 0; /* don't send reset */ 1256 return 0; /* don't send reset */
1260} 1257}
1261 1258