Commit 83e3609e authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by David S. Miller

[REQSK]: Move the syn_table destroy from tcp_listen_stop to reqsk_queue_destroy

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 080774a2
...@@ -89,6 +89,7 @@ struct listen_sock { ...@@ -89,6 +89,7 @@ struct listen_sock {
int qlen_young; int qlen_young;
int clock_hand; int clock_hand;
u32 hash_rnd; u32 hash_rnd;
u32 nr_table_entries;
struct request_sock *syn_table[0]; struct request_sock *syn_table[0];
}; };
...@@ -129,11 +130,13 @@ static inline struct listen_sock *reqsk_queue_yank_listen_sk(struct request_sock ...@@ -129,11 +130,13 @@ static inline struct listen_sock *reqsk_queue_yank_listen_sk(struct request_sock
return lopt; return lopt;
} }
static inline void reqsk_queue_destroy(struct request_sock_queue *queue) static inline void __reqsk_queue_destroy(struct request_sock_queue *queue)
{ {
kfree(reqsk_queue_yank_listen_sk(queue)); kfree(reqsk_queue_yank_listen_sk(queue));
} }
extern void reqsk_queue_destroy(struct request_sock_queue *queue);
static inline struct request_sock * static inline struct request_sock *
reqsk_queue_yank_acceptq(struct request_sock_queue *queue) reqsk_queue_yank_acceptq(struct request_sock_queue *queue)
{ {
......
...@@ -53,6 +53,7 @@ int reqsk_queue_alloc(struct request_sock_queue *queue, ...@@ -53,6 +53,7 @@ int reqsk_queue_alloc(struct request_sock_queue *queue,
get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd)); get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd));
rwlock_init(&queue->syn_wait_lock); rwlock_init(&queue->syn_wait_lock);
queue->rskq_accept_head = queue->rskq_accept_head = NULL; queue->rskq_accept_head = queue->rskq_accept_head = NULL;
lopt->nr_table_entries = nr_table_entries;
write_lock_bh(&queue->syn_wait_lock); write_lock_bh(&queue->syn_wait_lock);
queue->listen_opt = lopt; queue->listen_opt = lopt;
...@@ -62,3 +63,28 @@ int reqsk_queue_alloc(struct request_sock_queue *queue, ...@@ -62,3 +63,28 @@ int reqsk_queue_alloc(struct request_sock_queue *queue,
} }
EXPORT_SYMBOL(reqsk_queue_alloc); EXPORT_SYMBOL(reqsk_queue_alloc);
void reqsk_queue_destroy(struct request_sock_queue *queue)
{
/* make all the listen_opt local to us */
struct listen_sock *lopt = reqsk_queue_yank_listen_sk(queue);
if (lopt->qlen != 0) {
int i;
for (i = 0; i < lopt->nr_table_entries; i++) {
struct request_sock *req;
while ((req = lopt->syn_table[i]) != NULL) {
lopt->syn_table[i] = req->dl_next;
lopt->qlen--;
reqsk_free(req);
}
}
}
BUG_TRAP(lopt->qlen == 0);
kfree(lopt);
}
EXPORT_SYMBOL(reqsk_queue_destroy);
...@@ -487,7 +487,7 @@ int tcp_listen_start(struct sock *sk) ...@@ -487,7 +487,7 @@ int tcp_listen_start(struct sock *sk)
} }
sk->sk_state = TCP_CLOSE; sk->sk_state = TCP_CLOSE;
reqsk_queue_destroy(&tp->accept_queue); __reqsk_queue_destroy(&tp->accept_queue);
return -EADDRINUSE; return -EADDRINUSE;
} }
...@@ -499,38 +499,23 @@ int tcp_listen_start(struct sock *sk) ...@@ -499,38 +499,23 @@ int tcp_listen_start(struct sock *sk)
static void tcp_listen_stop (struct sock *sk) static void tcp_listen_stop (struct sock *sk)
{ {
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
struct listen_sock *lopt;
struct request_sock *acc_req; struct request_sock *acc_req;
struct request_sock *req; struct request_sock *req;
int i;
tcp_delete_keepalive_timer(sk); tcp_delete_keepalive_timer(sk);
/* make all the listen_opt local to us */ /* make all the listen_opt local to us */
lopt = reqsk_queue_yank_listen_sk(&tp->accept_queue);
acc_req = reqsk_queue_yank_acceptq(&tp->accept_queue); acc_req = reqsk_queue_yank_acceptq(&tp->accept_queue);
if (lopt->qlen) { /* Following specs, it would be better either to send FIN
for (i = 0; i < TCP_SYNQ_HSIZE; i++) { * (and enter FIN-WAIT-1, it is normal close)
while ((req = lopt->syn_table[i]) != NULL) { * or to send active reset (abort).
lopt->syn_table[i] = req->dl_next; * Certainly, it is pretty dangerous while synflood, but it is
lopt->qlen--; * bad justification for our negligence 8)
reqsk_free(req); * To be honest, we are not able to make either
* of the variants now. --ANK
/* Following specs, it would be better either to send FIN */
* (and enter FIN-WAIT-1, it is normal close) reqsk_queue_destroy(&tp->accept_queue);
* or to send active reset (abort).
* Certainly, it is pretty dangerous while synflood, but it is
* bad justification for our negligence 8)
* To be honest, we are not able to make either
* of the variants now. --ANK
*/
}
}
}
BUG_TRAP(!lopt->qlen);
kfree(lopt);
while ((req = acc_req) != NULL) { while ((req = acc_req) != NULL) {
struct sock *child = req->sk; struct sock *child = req->sk;
......
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