Skip to content

Commit

Permalink
TCPCT part 1a: add request_values parameter for sending SYNACK
Browse files Browse the repository at this point in the history
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: [email protected]
Acked-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
was4 authored and davem330 committed Dec 3, 2009
1 parent e004840 commit e6b4d11
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 33 deletions.
8 changes: 7 additions & 1 deletion include/net/request_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,19 @@ struct sk_buff;
struct dst_entry;
struct proto;

/* empty to "strongly type" an otherwise void parameter.
*/
struct request_values {
};

struct request_sock_ops {
int family;
int obj_size;
struct kmem_cache *slab;
char *slab_name;
int (*rtx_syn_ack)(struct sock *sk,
struct request_sock *req);
struct request_sock *req,
struct request_values *rvp);
void (*send_ack)(struct sock *sk, struct sk_buff *skb,
struct request_sock *req);
void (*send_reset)(struct sock *sk,
Expand Down
3 changes: 2 additions & 1 deletion include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,8 @@ extern int tcp_connect(struct sock *sk);

extern struct sk_buff * tcp_make_synack(struct sock *sk,
struct dst_entry *dst,
struct request_sock *req);
struct request_sock *req,
struct request_values *rvp);

extern int tcp_disconnect(struct sock *sk, int flags);

Expand Down
5 changes: 3 additions & 2 deletions net/dccp/ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,8 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
return &rt->u.dst;
}

static int dccp_v4_send_response(struct sock *sk, struct request_sock *req)
static int dccp_v4_send_response(struct sock *sk, struct request_sock *req,
struct request_values *rv_unused)
{
int err = -1;
struct sk_buff *skb;
Expand Down Expand Up @@ -626,7 +627,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
dreq->dreq_iss = dccp_v4_init_sequence(skb);
dreq->dreq_service = service;

if (dccp_v4_send_response(sk, req))
if (dccp_v4_send_response(sk, req, NULL))
goto drop_and_free;

inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
Expand Down
5 changes: 3 additions & 2 deletions net/dccp/ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
}


static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)
static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
struct request_values *rv_unused)
{
struct inet6_request_sock *ireq6 = inet6_rsk(req);
struct ipv6_pinfo *np = inet6_sk(sk);
Expand Down Expand Up @@ -468,7 +469,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
dreq->dreq_iss = dccp_v6_init_sequence(skb);
dreq->dreq_service = service;

if (dccp_v6_send_response(sk, req))
if (dccp_v6_send_response(sk, req, NULL))
goto drop_and_free;

inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
Expand Down
2 changes: 1 addition & 1 deletion net/dccp/minisocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
* counter (backoff, monitored by dccp_response_timer).
*/
req->retrans++;
req->rsk_ops->rtx_syn_ack(sk, req);
req->rsk_ops->rtx_syn_ack(sk, req, NULL);
}
/* Network Duplicate, discard packet */
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/inet_connection_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
&expire, &resend);
if (!expire &&
(!resend ||
!req->rsk_ops->rtx_syn_ack(parent, req) ||
!req->rsk_ops->rtx_syn_ack(parent, req, NULL) ||
inet_rsk(req)->acked)) {
unsigned long timeo;

Expand Down
18 changes: 10 additions & 8 deletions net/ipv4/tcp_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,8 +742,9 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
* This still operates on a request_sock only, not on a big
* socket.
*/
static int __tcp_v4_send_synack(struct sock *sk, struct request_sock *req,
struct dst_entry *dst)
static int __tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst,
struct request_sock *req,
struct request_values *rvp)
{
const struct inet_request_sock *ireq = inet_rsk(req);
int err = -1;
Expand All @@ -753,7 +754,7 @@ static int __tcp_v4_send_synack(struct sock *sk, struct request_sock *req,
if (!dst && (dst = inet_csk_route_req(sk, req)) == NULL)
return -1;

skb = tcp_make_synack(sk, dst, req);
skb = tcp_make_synack(sk, dst, req, rvp);

if (skb) {
struct tcphdr *th = tcp_hdr(skb);
Expand All @@ -774,9 +775,10 @@ static int __tcp_v4_send_synack(struct sock *sk, struct request_sock *req,
return err;
}

static int tcp_v4_send_synack(struct sock *sk, struct request_sock *req)
static int tcp_v4_send_synack(struct sock *sk, struct request_sock *req,
struct request_values *rvp)
{
return __tcp_v4_send_synack(sk, req, NULL);
return __tcp_v4_send_synack(sk, NULL, req, rvp);
}

/*
Expand Down Expand Up @@ -1211,13 +1213,13 @@ static struct timewait_sock_ops tcp_timewait_sock_ops = {

int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
{
struct inet_request_sock *ireq;
struct tcp_options_received tmp_opt;
struct request_sock *req;
struct inet_request_sock *ireq;
struct dst_entry *dst = NULL;
__be32 saddr = ip_hdr(skb)->saddr;
__be32 daddr = ip_hdr(skb)->daddr;
__u32 isn = TCP_SKB_CB(skb)->when;
struct dst_entry *dst = NULL;
#ifdef CONFIG_SYN_COOKIES
int want_cookie = 0;
#else
Expand Down Expand Up @@ -1337,7 +1339,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
}
tcp_rsk(req)->snt_isn = isn;

if (__tcp_v4_send_synack(sk, req, dst) || want_cookie)
if (__tcp_v4_send_synack(sk, dst, req, NULL) || want_cookie)
goto drop_and_free;

inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/tcp_minisocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
* Enforce "SYN-ACK" according to figure 8, figure 6
* of RFC793, fixed by RFC1122.
*/
req->rsk_ops->rtx_syn_ack(sk, req);
req->rsk_ops->rtx_syn_ack(sk, req, NULL);
return NULL;
}

Expand Down
3 changes: 2 additions & 1 deletion net/ipv4/tcp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -2224,7 +2224,8 @@ int tcp_send_synack(struct sock *sk)

/* Prepare a SYN-ACK. */
struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
struct request_sock *req)
struct request_sock *req,
struct request_values *rvp)
{
struct inet_request_sock *ireq = inet_rsk(req);
struct tcp_sock *tp = tcp_sk(sk);
Expand Down
27 changes: 12 additions & 15 deletions net/ipv6/tcp_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
}


static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
struct request_values *rvp)
{
struct inet6_request_sock *treq = inet6_rsk(req);
struct ipv6_pinfo *np = inet6_sk(sk);
Expand Down Expand Up @@ -499,7 +500,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
goto done;

skb = tcp_make_synack(sk, dst, req);
skb = tcp_make_synack(sk, dst, req, rvp);
if (skb) {
struct tcphdr *th = tcp_hdr(skb);

Expand Down Expand Up @@ -1161,13 +1162,13 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
*/
static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
{
struct tcp_options_received tmp_opt;
struct request_sock *req;
struct inet6_request_sock *treq;
struct ipv6_pinfo *np = inet6_sk(sk);
struct tcp_options_received tmp_opt;
struct tcp_sock *tp = tcp_sk(sk);
struct request_sock *req = NULL;
__u32 isn = TCP_SKB_CB(skb)->when;
struct dst_entry *dst = __sk_dst_get(sk);
__u32 isn = TCP_SKB_CB(skb)->when;
#ifdef CONFIG_SYN_COOKIES
int want_cookie = 0;
#else
Expand Down Expand Up @@ -1239,23 +1240,19 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)

isn = tcp_v6_init_sequence(skb);
}

tcp_rsk(req)->snt_isn = isn;

security_inet_conn_request(sk, skb, req);

if (tcp_v6_send_synack(sk, req))
goto drop;
if (tcp_v6_send_synack(sk, req, NULL) || want_cookie)
goto drop_and_free;

if (!want_cookie) {
inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
return 0;
}
inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
return 0;

drop_and_free:
reqsk_free(req);
drop:
if (req)
reqsk_free(req);

return 0; /* don't send reset */
}

Expand Down

0 comments on commit e6b4d11

Please sign in to comment.