aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/request_sock.h18
-rw-r--r--net/core/request_sock.c35
2 files changed, 36 insertions, 17 deletions
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index 7aed02ce2b65..cff4608179c1 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -124,23 +124,7 @@ struct request_sock_queue {
124extern int reqsk_queue_alloc(struct request_sock_queue *queue, 124extern int reqsk_queue_alloc(struct request_sock_queue *queue,
125 unsigned int nr_table_entries); 125 unsigned int nr_table_entries);
126 126
127static inline struct listen_sock *reqsk_queue_yank_listen_sk(struct request_sock_queue *queue) 127extern void __reqsk_queue_destroy(struct request_sock_queue *queue);
128{
129 struct listen_sock *lopt;
130
131 write_lock_bh(&queue->syn_wait_lock);
132 lopt = queue->listen_opt;
133 queue->listen_opt = NULL;
134 write_unlock_bh(&queue->syn_wait_lock);
135
136 return lopt;
137}
138
139static inline void __reqsk_queue_destroy(struct request_sock_queue *queue)
140{
141 kfree(reqsk_queue_yank_listen_sk(queue));
142}
143
144extern void reqsk_queue_destroy(struct request_sock_queue *queue); 128extern void reqsk_queue_destroy(struct request_sock_queue *queue);
145 129
146static inline struct request_sock * 130static inline struct request_sock *
diff --git a/net/core/request_sock.c b/net/core/request_sock.c
index 5f0818d815e6..45aed75cb571 100644
--- a/net/core/request_sock.c
+++ b/net/core/request_sock.c
@@ -71,6 +71,41 @@ int reqsk_queue_alloc(struct request_sock_queue *queue,
71 71
72EXPORT_SYMBOL(reqsk_queue_alloc); 72EXPORT_SYMBOL(reqsk_queue_alloc);
73 73
74void __reqsk_queue_destroy(struct request_sock_queue *queue)
75{
76 struct listen_sock *lopt;
77 size_t lopt_size;
78
79 /*
80 * this is an error recovery path only
81 * no locking needed and the lopt is not NULL
82 */
83
84 lopt = queue->listen_opt;
85 lopt_size = sizeof(struct listen_sock) +
86 lopt->nr_table_entries * sizeof(struct request_sock *);
87
88 if (lopt_size > PAGE_SIZE)
89 vfree(lopt);
90 else
91 kfree(lopt);
92}
93
94EXPORT_SYMBOL(__reqsk_queue_destroy);
95
96static inline struct listen_sock *reqsk_queue_yank_listen_sk(
97 struct request_sock_queue *queue)
98{
99 struct listen_sock *lopt;
100
101 write_lock_bh(&queue->syn_wait_lock);
102 lopt = queue->listen_opt;
103 queue->listen_opt = NULL;
104 write_unlock_bh(&queue->syn_wait_lock);
105
106 return lopt;
107}
108
74void reqsk_queue_destroy(struct request_sock_queue *queue) 109void reqsk_queue_destroy(struct request_sock_queue *queue)
75{ 110{
76 /* make all the listen_opt local to us */ 111 /* make all the listen_opt local to us */