mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-30 19:15:14 +00:00
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: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a998f712f7
commit
52452c5425
14 changed files with 67 additions and 74 deletions
|
@ -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,
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
* 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)
|
||||||
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,
|
||||||
|
|
||||||
/* 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,
|
||||||
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)
|
||||||
{
|
{
|
||||||
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);
|
||||||
* 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,
|
||||||
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 @@ drop:
|
||||||
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,
|
||||||
#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,
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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,
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
* 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);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
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,
|
||||||
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 @@ embryonic_reset:
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
{
|
{
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
/* 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,
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue