diff options
Diffstat (limited to 'net/ipv4/inet_connection_sock.c')
-rw-r--r-- | net/ipv4/inet_connection_sock.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 5c3dd6267ed3..8976ca423a07 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -564,6 +564,40 @@ int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req) | |||
564 | } | 564 | } |
565 | EXPORT_SYMBOL(inet_rtx_syn_ack); | 565 | EXPORT_SYMBOL(inet_rtx_syn_ack); |
566 | 566 | ||
567 | /* return true if req was found in the syn_table[] */ | ||
568 | static bool reqsk_queue_unlink(struct request_sock_queue *queue, | ||
569 | struct request_sock *req) | ||
570 | { | ||
571 | struct listen_sock *lopt = queue->listen_opt; | ||
572 | struct request_sock **prev; | ||
573 | bool found = false; | ||
574 | |||
575 | spin_lock(&queue->syn_wait_lock); | ||
576 | |||
577 | for (prev = &lopt->syn_table[req->rsk_hash]; *prev != NULL; | ||
578 | prev = &(*prev)->dl_next) { | ||
579 | if (*prev == req) { | ||
580 | *prev = req->dl_next; | ||
581 | found = true; | ||
582 | break; | ||
583 | } | ||
584 | } | ||
585 | |||
586 | spin_unlock(&queue->syn_wait_lock); | ||
587 | if (del_timer(&req->rsk_timer)) | ||
588 | reqsk_put(req); | ||
589 | return found; | ||
590 | } | ||
591 | |||
592 | void inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req) | ||
593 | { | ||
594 | if (reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req)) { | ||
595 | reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req); | ||
596 | reqsk_put(req); | ||
597 | } | ||
598 | } | ||
599 | EXPORT_SYMBOL(inet_csk_reqsk_queue_drop); | ||
600 | |||
567 | static void reqsk_timer_handler(unsigned long data) | 601 | static void reqsk_timer_handler(unsigned long data) |
568 | { | 602 | { |
569 | struct request_sock *req = (struct request_sock *)data; | 603 | struct request_sock *req = (struct request_sock *)data; |