[NET] Generalise TCP's struct open_request minisock infrastructure
Kept this first changeset minimal, without changing existing names to ease peer review. Basicaly tcp_openreq_alloc now receives the or_calltable, that in turn has two new members: ->slab, that replaces tcp_openreq_cachep ->obj_size, to inform the size of the openreq descendant for a specific protocol The protocol specific fields in struct open_request were moved to a class hierarchy, with the things that are common to all connection oriented PF_INET protocols in struct inet_request_sock, the TCP ones in tcp_request_sock, that is an inet_request_sock, that is an open_request. I.e. this uses the same approach used for the struct sock class hierarchy, with sk_prot indicating if the protocol wants to use the open_request infrastructure by filling in sk_prot->rsk_prot with an or_calltable. Results? Performance is improved and TCP v4 now uses only 64 bytes per open request minisock, down from 96 without this patch :-) Next changeset will rename some of the structs, fields and functions mentioned above, struct or_calltable is way unclear, better name it struct request_sock_ops, s/struct open_request/struct request_sock/g, etc. Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
1944972d3b
commit
2e6599cb89
@@ -190,6 +190,8 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
|
||||
struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
|
||||
struct ip_options *opt)
|
||||
{
|
||||
struct inet_request_sock *ireq;
|
||||
struct tcp_request_sock *treq;
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
__u32 cookie = ntohl(skb->h.th->ack_seq) - 1;
|
||||
struct sock *ret = sk;
|
||||
@@ -209,19 +211,20 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
|
||||
|
||||
NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESRECV);
|
||||
|
||||
req = tcp_openreq_alloc();
|
||||
ret = NULL;
|
||||
req = tcp_openreq_alloc(&or_ipv4); /* for safety */
|
||||
if (!req)
|
||||
goto out;
|
||||
|
||||
req->rcv_isn = htonl(skb->h.th->seq) - 1;
|
||||
req->snt_isn = cookie;
|
||||
ireq = inet_rsk(req);
|
||||
treq = tcp_rsk(req);
|
||||
treq->rcv_isn = htonl(skb->h.th->seq) - 1;
|
||||
treq->snt_isn = cookie;
|
||||
req->mss = mss;
|
||||
req->rmt_port = skb->h.th->source;
|
||||
req->af.v4_req.loc_addr = skb->nh.iph->daddr;
|
||||
req->af.v4_req.rmt_addr = skb->nh.iph->saddr;
|
||||
req->class = &or_ipv4; /* for savety */
|
||||
req->af.v4_req.opt = NULL;
|
||||
ireq->rmt_port = skb->h.th->source;
|
||||
ireq->loc_addr = skb->nh.iph->daddr;
|
||||
ireq->rmt_addr = skb->nh.iph->saddr;
|
||||
ireq->opt = NULL;
|
||||
|
||||
/* We throwed the options of the initial SYN away, so we hope
|
||||
* the ACK carries the same options again (see RFC1122 4.2.3.8)
|
||||
@@ -229,17 +232,15 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
|
||||
if (opt && opt->optlen) {
|
||||
int opt_size = sizeof(struct ip_options) + opt->optlen;
|
||||
|
||||
req->af.v4_req.opt = kmalloc(opt_size, GFP_ATOMIC);
|
||||
if (req->af.v4_req.opt) {
|
||||
if (ip_options_echo(req->af.v4_req.opt, skb)) {
|
||||
kfree(req->af.v4_req.opt);
|
||||
req->af.v4_req.opt = NULL;
|
||||
}
|
||||
ireq->opt = kmalloc(opt_size, GFP_ATOMIC);
|
||||
if (ireq->opt != NULL && ip_options_echo(ireq->opt, skb)) {
|
||||
kfree(ireq->opt);
|
||||
ireq->opt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
req->snd_wscale = req->rcv_wscale = req->tstamp_ok = 0;
|
||||
req->wscale_ok = req->sack_ok = 0;
|
||||
ireq->snd_wscale = ireq->rcv_wscale = ireq->tstamp_ok = 0;
|
||||
ireq->wscale_ok = ireq->sack_ok = 0;
|
||||
req->expires = 0UL;
|
||||
req->retrans = 0;
|
||||
|
||||
@@ -253,8 +254,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
|
||||
struct flowi fl = { .nl_u = { .ip4_u =
|
||||
{ .daddr = ((opt && opt->srr) ?
|
||||
opt->faddr :
|
||||
req->af.v4_req.rmt_addr),
|
||||
.saddr = req->af.v4_req.loc_addr,
|
||||
ireq->rmt_addr),
|
||||
.saddr = ireq->loc_addr,
|
||||
.tos = RT_CONN_FLAGS(sk) } },
|
||||
.proto = IPPROTO_TCP,
|
||||
.uli_u = { .ports =
|
||||
@@ -272,7 +273,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
|
||||
&req->rcv_wnd, &req->window_clamp,
|
||||
0, &rcv_wscale);
|
||||
/* BTW win scale with syncookies is 0 by definition */
|
||||
req->rcv_wscale = rcv_wscale;
|
||||
ireq->rcv_wscale = rcv_wscale;
|
||||
|
||||
ret = get_cookie_sock(sk, skb, req, &rt->u.dst);
|
||||
out: return ret;
|
||||
|
Reference in New Issue
Block a user