Commit 52452c54 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

inet: drop prev pointer handling in request sock

When request sock are put in ehash table, the whole notion
of having a previous request to update dl_next is pointless.

Also, following patch will get rid of big purge timer,
so we want to delete a request sock without holding listener lock.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a998f712
...@@ -29,7 +29,6 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, struct flowi6 *fl6, ...@@ -29,7 +29,6 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, struct flowi6 *fl6,
const struct request_sock *req); const struct request_sock *req);
struct request_sock *inet6_csk_search_req(const struct sock *sk, struct request_sock *inet6_csk_search_req(const struct sock *sk,
struct request_sock ***prevp,
const __be16 rport, const __be16 rport,
const struct in6_addr *raddr, const struct in6_addr *raddr,
const struct in6_addr *laddr, const struct in6_addr *laddr,
......
...@@ -257,7 +257,6 @@ inet_csk_rto_backoff(const struct inet_connection_sock *icsk, ...@@ -257,7 +257,6 @@ inet_csk_rto_backoff(const struct inet_connection_sock *icsk,
struct sock *inet_csk_accept(struct sock *sk, int flags, int *err); struct sock *inet_csk_accept(struct sock *sk, int flags, int *err);
struct request_sock *inet_csk_search_req(const struct sock *sk, struct request_sock *inet_csk_search_req(const struct sock *sk,
struct request_sock ***prevp,
const __be16 rport, const __be16 rport,
const __be32 raddr, const __be32 raddr,
const __be32 laddr); const __be32 laddr);
...@@ -310,17 +309,15 @@ static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk) ...@@ -310,17 +309,15 @@ static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk)
} }
static inline void inet_csk_reqsk_queue_unlink(struct sock *sk, static inline void inet_csk_reqsk_queue_unlink(struct sock *sk,
struct request_sock *req, struct request_sock *req)
struct request_sock **prev)
{ {
reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req, prev); reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req);
} }
static inline void inet_csk_reqsk_queue_drop(struct sock *sk, static inline void inet_csk_reqsk_queue_drop(struct sock *sk,
struct request_sock *req, struct request_sock *req)
struct request_sock **prev)
{ {
inet_csk_reqsk_queue_unlink(sk, req, prev); inet_csk_reqsk_queue_unlink(sk, req);
inet_csk_reqsk_queue_removed(sk, req); inet_csk_reqsk_queue_removed(sk, req);
reqsk_free(req); reqsk_free(req);
} }
......
...@@ -50,6 +50,7 @@ int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req); ...@@ -50,6 +50,7 @@ int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req);
struct request_sock { struct request_sock {
struct sock_common __req_common; struct sock_common __req_common;
#define rsk_refcnt __req_common.skc_refcnt #define rsk_refcnt __req_common.skc_refcnt
#define rsk_hash __req_common.skc_hash
struct request_sock *dl_next; struct request_sock *dl_next;
struct sock *rsk_listener; struct sock *rsk_listener;
...@@ -216,11 +217,16 @@ static inline int reqsk_queue_empty(struct request_sock_queue *queue) ...@@ -216,11 +217,16 @@ static inline int reqsk_queue_empty(struct request_sock_queue *queue)
} }
static inline void reqsk_queue_unlink(struct request_sock_queue *queue, static inline void reqsk_queue_unlink(struct request_sock_queue *queue,
struct request_sock *req, struct request_sock *req)
struct request_sock **prev_req)
{ {
struct listen_sock *lopt = queue->listen_opt;
struct request_sock **prev;
write_lock(&queue->syn_wait_lock); write_lock(&queue->syn_wait_lock);
*prev_req = req->dl_next; prev = &lopt->syn_table[req->rsk_hash];
while (*prev != req)
prev = &(*prev)->dl_next;
*prev = req->dl_next;
write_unlock(&queue->syn_wait_lock); write_unlock(&queue->syn_wait_lock);
} }
...@@ -300,7 +306,6 @@ static inline void reqsk_queue_hash_req(struct request_sock_queue *queue, ...@@ -300,7 +306,6 @@ static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
req->num_retrans = 0; req->num_retrans = 0;
req->num_timeout = 0; req->num_timeout = 0;
req->sk = NULL; req->sk = NULL;
req->dl_next = lopt->syn_table[hash];
/* before letting lookups find us, make sure all req fields /* before letting lookups find us, make sure all req fields
* are committed to memory and refcnt initialized. * are committed to memory and refcnt initialized.
...@@ -308,7 +313,9 @@ static inline void reqsk_queue_hash_req(struct request_sock_queue *queue, ...@@ -308,7 +313,9 @@ static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
smp_wmb(); smp_wmb();
atomic_set(&req->rsk_refcnt, 1); atomic_set(&req->rsk_refcnt, 1);
req->rsk_hash = hash;
write_lock(&queue->syn_wait_lock); write_lock(&queue->syn_wait_lock);
req->dl_next = lopt->syn_table[hash];
lopt->syn_table[hash] = req; lopt->syn_table[hash] = req;
write_unlock(&queue->syn_wait_lock); write_unlock(&queue->syn_wait_lock);
} }
......
...@@ -406,8 +406,7 @@ enum tcp_tw_status tcp_timewait_state_process(struct inet_timewait_sock *tw, ...@@ -406,8 +406,7 @@ enum tcp_tw_status tcp_timewait_state_process(struct inet_timewait_sock *tw,
struct sk_buff *skb, struct sk_buff *skb,
const struct tcphdr *th); const struct tcphdr *th);
struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
struct request_sock *req, struct request_sock **prev, struct request_sock *req, bool fastopen);
bool fastopen);
int tcp_child_process(struct sock *parent, struct sock *child, int tcp_child_process(struct sock *parent, struct sock *child,
struct sk_buff *skb); struct sk_buff *skb);
void tcp_enter_loss(struct sock *sk); void tcp_enter_loss(struct sock *sk);
......
...@@ -280,8 +280,7 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb, ...@@ -280,8 +280,7 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb,
struct request_sock *req, struct request_sock *req,
struct dst_entry *dst); struct dst_entry *dst);
struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
struct request_sock *req, struct request_sock *req);
struct request_sock **prev);
int dccp_child_process(struct sock *parent, struct sock *child, int dccp_child_process(struct sock *parent, struct sock *child,
struct sk_buff *skb); struct sk_buff *skb);
......
...@@ -288,11 +288,11 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) ...@@ -288,11 +288,11 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
} }
switch (sk->sk_state) { switch (sk->sk_state) {
struct request_sock *req , **prev; struct request_sock *req;
case DCCP_LISTEN: case DCCP_LISTEN:
if (sock_owned_by_user(sk)) if (sock_owned_by_user(sk))
goto out; goto out;
req = inet_csk_search_req(sk, &prev, dh->dccph_dport, req = inet_csk_search_req(sk, dh->dccph_dport,
iph->daddr, iph->saddr); iph->daddr, iph->saddr);
if (!req) if (!req)
goto out; goto out;
...@@ -314,7 +314,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) ...@@ -314,7 +314,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
* created socket, and POSIX does not want network * created socket, and POSIX does not want network
* errors returned from accept(). * errors returned from accept().
*/ */
inet_csk_reqsk_queue_drop(sk, req, prev); inet_csk_reqsk_queue_drop(sk, req);
goto out; goto out;
case DCCP_REQUESTING: case DCCP_REQUESTING:
...@@ -448,13 +448,11 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) ...@@ -448,13 +448,11 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
const struct dccp_hdr *dh = dccp_hdr(skb); const struct dccp_hdr *dh = dccp_hdr(skb);
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
struct sock *nsk; struct sock *nsk;
struct request_sock **prev;
/* Find possible connection requests. */ /* Find possible connection requests. */
struct request_sock *req = inet_csk_search_req(sk, &prev, struct request_sock *req = inet_csk_search_req(sk, dh->dccph_sport,
dh->dccph_sport,
iph->saddr, iph->daddr); iph->saddr, iph->daddr);
if (req != NULL) if (req)
return dccp_check_req(sk, skb, req, prev); return dccp_check_req(sk, skb, req);
nsk = inet_lookup_established(sock_net(sk), &dccp_hashinfo, nsk = inet_lookup_established(sock_net(sk), &dccp_hashinfo,
iph->saddr, dh->dccph_sport, iph->saddr, dh->dccph_sport,
......
...@@ -149,12 +149,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -149,12 +149,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
/* Might be for an request_sock */ /* Might be for an request_sock */
switch (sk->sk_state) { switch (sk->sk_state) {
struct request_sock *req, **prev; struct request_sock *req;
case DCCP_LISTEN: case DCCP_LISTEN:
if (sock_owned_by_user(sk)) if (sock_owned_by_user(sk))
goto out; goto out;
req = inet6_csk_search_req(sk, &prev, dh->dccph_dport, req = inet6_csk_search_req(sk, dh->dccph_dport,
&hdr->daddr, &hdr->saddr, &hdr->daddr, &hdr->saddr,
inet6_iif(skb)); inet6_iif(skb));
if (req == NULL) if (req == NULL)
...@@ -172,7 +172,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -172,7 +172,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
goto out; goto out;
} }
inet_csk_reqsk_queue_drop(sk, req, prev); inet_csk_reqsk_queue_drop(sk, req);
goto out; goto out;
case DCCP_REQUESTING: case DCCP_REQUESTING:
...@@ -317,16 +317,13 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) ...@@ -317,16 +317,13 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
{ {
const struct dccp_hdr *dh = dccp_hdr(skb); const struct dccp_hdr *dh = dccp_hdr(skb);
const struct ipv6hdr *iph = ipv6_hdr(skb); const struct ipv6hdr *iph = ipv6_hdr(skb);
struct request_sock *req;
struct sock *nsk; struct sock *nsk;
struct request_sock **prev;
/* Find possible connection requests. */ req = inet6_csk_search_req(sk, dh->dccph_sport, &iph->saddr,
struct request_sock *req = inet6_csk_search_req(sk, &prev, &iph->daddr, inet6_iif(skb));
dh->dccph_sport,
&iph->saddr,
&iph->daddr,
inet6_iif(skb));
if (req != NULL) if (req != NULL)
return dccp_check_req(sk, skb, req, prev); return dccp_check_req(sk, skb, req);
nsk = __inet6_lookup_established(sock_net(sk), &dccp_hashinfo, nsk = __inet6_lookup_established(sock_net(sk), &dccp_hashinfo,
&iph->saddr, dh->dccph_sport, &iph->saddr, dh->dccph_sport,
......
...@@ -152,8 +152,7 @@ EXPORT_SYMBOL_GPL(dccp_create_openreq_child); ...@@ -152,8 +152,7 @@ EXPORT_SYMBOL_GPL(dccp_create_openreq_child);
* as an request_sock. * as an request_sock.
*/ */
struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
struct request_sock *req, struct request_sock *req)
struct request_sock **prev)
{ {
struct sock *child = NULL; struct sock *child = NULL;
struct dccp_request_sock *dreq = dccp_rsk(req); struct dccp_request_sock *dreq = dccp_rsk(req);
...@@ -200,7 +199,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, ...@@ -200,7 +199,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
if (child == NULL) if (child == NULL)
goto listen_overflow; goto listen_overflow;
inet_csk_reqsk_queue_unlink(sk, req, prev); inet_csk_reqsk_queue_unlink(sk, req);
inet_csk_reqsk_queue_removed(sk, req); inet_csk_reqsk_queue_removed(sk, req);
inet_csk_reqsk_queue_add(sk, req, child); inet_csk_reqsk_queue_add(sk, req, child);
out: out:
...@@ -212,7 +211,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, ...@@ -212,7 +211,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET) if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET)
req->rsk_ops->send_reset(sk, skb); req->rsk_ops->send_reset(sk, skb);
inet_csk_reqsk_queue_drop(sk, req, prev); inet_csk_reqsk_queue_drop(sk, req);
goto out; goto out;
} }
......
...@@ -480,18 +480,17 @@ static inline u32 inet_synq_hash(const __be32 raddr, const __be16 rport, ...@@ -480,18 +480,17 @@ static inline u32 inet_synq_hash(const __be32 raddr, const __be16 rport,
#endif #endif
struct request_sock *inet_csk_search_req(const struct sock *sk, struct request_sock *inet_csk_search_req(const struct sock *sk,
struct request_sock ***prevp,
const __be16 rport, const __be32 raddr, const __be16 rport, const __be32 raddr,
const __be32 laddr) const __be32 laddr)
{ {
const struct inet_connection_sock *icsk = inet_csk(sk); const struct inet_connection_sock *icsk = inet_csk(sk);
struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
struct request_sock *req, **prev; struct request_sock *req;
for (prev = &lopt->syn_table[inet_synq_hash(raddr, rport, lopt->hash_rnd, for (req = lopt->syn_table[inet_synq_hash(raddr, rport, lopt->hash_rnd,
lopt->nr_table_entries)]; lopt->nr_table_entries)];
(req = *prev) != NULL; req != NULL;
prev = &req->dl_next) { req = req->dl_next) {
const struct inet_request_sock *ireq = inet_rsk(req); const struct inet_request_sock *ireq = inet_rsk(req);
if (ireq->ir_rmt_port == rport && if (ireq->ir_rmt_port == rport &&
...@@ -499,7 +498,6 @@ struct request_sock *inet_csk_search_req(const struct sock *sk, ...@@ -499,7 +498,6 @@ struct request_sock *inet_csk_search_req(const struct sock *sk,
ireq->ir_loc_addr == laddr && ireq->ir_loc_addr == laddr &&
AF_INET_FAMILY(req->rsk_ops->family)) { AF_INET_FAMILY(req->rsk_ops->family)) {
WARN_ON(req->sk); WARN_ON(req->sk);
*prevp = prev;
break; break;
} }
} }
...@@ -610,7 +608,10 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, ...@@ -610,7 +608,10 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
i = lopt->clock_hand; i = lopt->clock_hand;
do { do {
reqp=&lopt->syn_table[i]; reqp = &lopt->syn_table[i];
if (!*reqp)
goto next_bucket;
write_lock(&queue->syn_wait_lock);
while ((req = *reqp) != NULL) { while ((req = *reqp) != NULL) {
if (time_after_eq(now, req->expires)) { if (time_after_eq(now, req->expires)) {
int expire = 0, resend = 0; int expire = 0, resend = 0;
...@@ -635,14 +636,15 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, ...@@ -635,14 +636,15 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
} }
/* Drop this request */ /* Drop this request */
inet_csk_reqsk_queue_unlink(parent, req, reqp); *reqp = req->dl_next;
reqsk_queue_removed(queue, req); reqsk_queue_removed(queue, req);
reqsk_put(req); reqsk_put(req);
continue; continue;
} }
reqp = &req->dl_next; reqp = &req->dl_next;
} }
write_unlock(&queue->syn_wait_lock);
next_bucket:
i = (i + 1) & (lopt->nr_table_entries - 1); i = (i + 1) & (lopt->nr_table_entries - 1);
} while (--budget > 0); } while (--budget > 0);
......
...@@ -5694,7 +5694,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, ...@@ -5694,7 +5694,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV && WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV &&
sk->sk_state != TCP_FIN_WAIT1); sk->sk_state != TCP_FIN_WAIT1);
if (tcp_check_req(sk, skb, req, NULL, true) == NULL) if (tcp_check_req(sk, skb, req, true) == NULL)
goto discard; goto discard;
} }
......
...@@ -458,12 +458,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) ...@@ -458,12 +458,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
} }
switch (sk->sk_state) { switch (sk->sk_state) {
struct request_sock *req, **prev; struct request_sock *req;
case TCP_LISTEN: case TCP_LISTEN:
if (sock_owned_by_user(sk)) if (sock_owned_by_user(sk))
goto out; goto out;
req = inet_csk_search_req(sk, &prev, th->dest, req = inet_csk_search_req(sk, th->dest,
iph->daddr, iph->saddr); iph->daddr, iph->saddr);
if (!req) if (!req)
goto out; goto out;
...@@ -484,7 +484,7 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) ...@@ -484,7 +484,7 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
* created socket, and POSIX does not want network * created socket, and POSIX does not want network
* errors returned from accept(). * errors returned from accept().
*/ */
inet_csk_reqsk_queue_drop(sk, req, prev); inet_csk_reqsk_queue_drop(sk, req);
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
goto out; goto out;
...@@ -1392,15 +1392,14 @@ EXPORT_SYMBOL(tcp_v4_syn_recv_sock); ...@@ -1392,15 +1392,14 @@ EXPORT_SYMBOL(tcp_v4_syn_recv_sock);
static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
{ {
struct tcphdr *th = tcp_hdr(skb); const struct tcphdr *th = tcp_hdr(skb);
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
struct request_sock *req;
struct sock *nsk; struct sock *nsk;
struct request_sock **prev;
/* Find possible connection requests. */ req = inet_csk_search_req(sk, th->source, iph->saddr, iph->daddr);
struct request_sock *req = inet_csk_search_req(sk, &prev, th->source,
iph->saddr, iph->daddr);
if (req) if (req)
return tcp_check_req(sk, skb, req, prev, false); return tcp_check_req(sk, skb, req, false);
nsk = inet_lookup_established(sock_net(sk), &tcp_hashinfo, iph->saddr, nsk = inet_lookup_established(sock_net(sk), &tcp_hashinfo, iph->saddr,
th->source, iph->daddr, th->dest, inet_iif(skb)); th->source, iph->daddr, th->dest, inet_iif(skb));
......
...@@ -572,7 +572,6 @@ EXPORT_SYMBOL(tcp_create_openreq_child); ...@@ -572,7 +572,6 @@ EXPORT_SYMBOL(tcp_create_openreq_child);
struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
struct request_sock *req, struct request_sock *req,
struct request_sock **prev,
bool fastopen) bool fastopen)
{ {
struct tcp_options_received tmp_opt; struct tcp_options_received tmp_opt;
...@@ -766,7 +765,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, ...@@ -766,7 +765,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
if (child == NULL) if (child == NULL)
goto listen_overflow; goto listen_overflow;
inet_csk_reqsk_queue_unlink(sk, req, prev); inet_csk_reqsk_queue_unlink(sk, req);
inet_csk_reqsk_queue_removed(sk, req); inet_csk_reqsk_queue_removed(sk, req);
inet_csk_reqsk_queue_add(sk, req, child); inet_csk_reqsk_queue_add(sk, req, child);
...@@ -791,7 +790,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, ...@@ -791,7 +790,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
tcp_reset(sk); tcp_reset(sk);
} }
if (!fastopen) { if (!fastopen) {
inet_csk_reqsk_queue_drop(sk, req, prev); inet_csk_reqsk_queue_drop(sk, req);
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS);
} }
return NULL; return NULL;
......
...@@ -113,7 +113,6 @@ static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport, ...@@ -113,7 +113,6 @@ static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport,
} }
struct request_sock *inet6_csk_search_req(const struct sock *sk, struct request_sock *inet6_csk_search_req(const struct sock *sk,
struct request_sock ***prevp,
const __be16 rport, const __be16 rport,
const struct in6_addr *raddr, const struct in6_addr *raddr,
const struct in6_addr *laddr, const struct in6_addr *laddr,
...@@ -121,13 +120,13 @@ struct request_sock *inet6_csk_search_req(const struct sock *sk, ...@@ -121,13 +120,13 @@ struct request_sock *inet6_csk_search_req(const struct sock *sk,
{ {
const struct inet_connection_sock *icsk = inet_csk(sk); const struct inet_connection_sock *icsk = inet_csk(sk);
struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
struct request_sock *req, **prev; struct request_sock *req;
for (prev = &lopt->syn_table[inet6_synq_hash(raddr, rport, for (req = lopt->syn_table[inet6_synq_hash(raddr, rport,
lopt->hash_rnd, lopt->hash_rnd,
lopt->nr_table_entries)]; lopt->nr_table_entries)];
(req = *prev) != NULL; req != NULL;
prev = &req->dl_next) { req = req->dl_next) {
const struct inet_request_sock *ireq = inet_rsk(req); const struct inet_request_sock *ireq = inet_rsk(req);
if (ireq->ir_rmt_port == rport && if (ireq->ir_rmt_port == rport &&
...@@ -136,7 +135,6 @@ struct request_sock *inet6_csk_search_req(const struct sock *sk, ...@@ -136,7 +135,6 @@ struct request_sock *inet6_csk_search_req(const struct sock *sk,
ipv6_addr_equal(&ireq->ir_v6_loc_addr, laddr) && ipv6_addr_equal(&ireq->ir_v6_loc_addr, laddr) &&
(!ireq->ir_iif || ireq->ir_iif == iif)) { (!ireq->ir_iif || ireq->ir_iif == iif)) {
WARN_ON(req->sk != NULL); WARN_ON(req->sk != NULL);
*prevp = prev;
return req; return req;
} }
} }
......
...@@ -403,13 +403,13 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -403,13 +403,13 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
/* Might be for an request_sock */ /* Might be for an request_sock */
switch (sk->sk_state) { switch (sk->sk_state) {
struct request_sock *req, **prev; struct request_sock *req;
case TCP_LISTEN: case TCP_LISTEN:
if (sock_owned_by_user(sk)) if (sock_owned_by_user(sk))
goto out; goto out;
/* Note : We use inet6_iif() here, not tcp_v6_iif() */ /* Note : We use inet6_iif() here, not tcp_v6_iif() */
req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr, req = inet6_csk_search_req(sk, th->dest, &hdr->daddr,
&hdr->saddr, inet6_iif(skb)); &hdr->saddr, inet6_iif(skb));
if (!req) if (!req)
goto out; goto out;
...@@ -424,7 +424,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -424,7 +424,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
goto out; goto out;
} }
inet_csk_reqsk_queue_drop(sk, req, prev); inet_csk_reqsk_queue_drop(sk, req);
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
goto out; goto out;
...@@ -980,16 +980,16 @@ static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, ...@@ -980,16 +980,16 @@ static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
static struct sock *tcp_v6_hnd_req(struct sock *sk, struct sk_buff *skb) static struct sock *tcp_v6_hnd_req(struct sock *sk, struct sk_buff *skb)
{ {
struct request_sock *req, **prev;
const struct tcphdr *th = tcp_hdr(skb); const struct tcphdr *th = tcp_hdr(skb);
struct request_sock *req;
struct sock *nsk; struct sock *nsk;
/* Find possible connection requests. */ /* Find possible connection requests. */
req = inet6_csk_search_req(sk, &prev, th->source, req = inet6_csk_search_req(sk, th->source,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->saddr,
&ipv6_hdr(skb)->daddr, tcp_v6_iif(skb)); &ipv6_hdr(skb)->daddr, tcp_v6_iif(skb));
if (req) if (req)
return tcp_check_req(sk, skb, req, prev, false); return tcp_check_req(sk, skb, req, false);
nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo,
&ipv6_hdr(skb)->saddr, th->source, &ipv6_hdr(skb)->saddr, th->source,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment