#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/types.h>
+#include <linux/bug.h>
#include <net/sock.h>
struct dst_entry;
struct proto;
+/* empty to "strongly type" an otherwise void parameter.
+ */
+struct request_values {
+};
+
struct request_sock_ops {
int family;
- kmem_cache_t *slab;
int obj_size;
+ struct kmem_cache *slab;
+ char *slab_name;
int (*rtx_syn_ack)(struct sock *sk,
struct request_sock *req,
- struct dst_entry *dst);
- void (*send_ack)(struct sk_buff *skb,
+ struct request_values *rvp);
+ void (*send_ack)(struct sock *sk, struct sk_buff *skb,
struct request_sock *req);
- void (*send_reset)(struct sk_buff *skb);
+ void (*send_reset)(struct sock *sk,
+ struct sk_buff *skb);
void (*destructor)(struct request_sock *req);
+ void (*syn_ack_timeout)(struct sock *sk,
+ struct request_sock *req);
};
/* struct request_sock - mini sock to represent a connection request
struct request_sock *dl_next; /* Must be first member! */
u16 mss;
u8 retrans;
- u8 __pad;
+ u8 cookie_ts; /* syncookie: encode tcpopts in timestamp */
/* The following two fields can be easily recomputed I think -AK */
u32 window_clamp; /* window clamp at creation time */
u32 rcv_wnd; /* rcv_wnd offered first time */
u32 ts_recent;
unsigned long expires;
- struct request_sock_ops *rsk_ops;
+ const struct request_sock_ops *rsk_ops;
struct sock *sk;
+ u32 secid;
+ u32 peer_secid;
};
-static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops)
+static inline struct request_sock *reqsk_alloc(const struct request_sock_ops *ops)
{
- struct request_sock *req = kmem_cache_alloc(ops->slab, SLAB_ATOMIC);
+ struct request_sock *req = kmem_cache_alloc(ops->slab, GFP_ATOMIC);
if (req != NULL)
req->rsk_ops = ops;
extern int sysctl_max_syn_backlog;
-/** struct tcp_listen_opt - listen state
+/** struct listen_sock - listen state
*
* @max_qlen_log - log_2 of maximal queued SYNs/REQUESTs
*/
-struct tcp_listen_opt {
+struct listen_sock {
u8 max_qlen_log;
/* 3 bytes hole, try to use */
int qlen;
int qlen_young;
int clock_hand;
u32 hash_rnd;
+ u32 nr_table_entries;
struct request_sock *syn_table[0];
};
*
* @rskq_accept_head - FIFO head of established children
* @rskq_accept_tail - FIFO tail of established children
+ * @rskq_defer_accept - User waits for some data after accept()
* @syn_wait_lock - serializer
*
* %syn_wait_lock is necessary only to avoid proc interface having to grab the main
struct request_sock *rskq_accept_head;
struct request_sock *rskq_accept_tail;
rwlock_t syn_wait_lock;
- struct tcp_listen_opt *listen_opt;
+ u8 rskq_defer_accept;
+ /* 3 bytes hole, try to pack */
+ struct listen_sock *listen_opt;
};
extern int reqsk_queue_alloc(struct request_sock_queue *queue,
- const int nr_table_entries);
-
-static inline struct tcp_listen_opt *reqsk_queue_yank_listen_sk(struct request_sock_queue *queue)
-{
- struct tcp_listen_opt *lopt;
+ unsigned int nr_table_entries);
- write_lock_bh(&queue->syn_wait_lock);
- lopt = queue->listen_opt;
- queue->listen_opt = NULL;
- write_unlock_bh(&queue->syn_wait_lock);
-
- return lopt;
-}
-
-static inline void reqsk_queue_destroy(struct request_sock_queue *queue)
-{
- kfree(reqsk_queue_yank_listen_sk(queue));
-}
+extern void __reqsk_queue_destroy(struct request_sock_queue *queue);
+extern void reqsk_queue_destroy(struct request_sock_queue *queue);
static inline struct request_sock *
reqsk_queue_yank_acceptq(struct request_sock_queue *queue)
{
struct request_sock *req = queue->rskq_accept_head;
- queue->rskq_accept_head = queue->rskq_accept_head = NULL;
+ queue->rskq_accept_head = NULL;
return req;
}
{
struct request_sock *req = queue->rskq_accept_head;
- BUG_TRAP(req != NULL);
+ WARN_ON(req == NULL);
queue->rskq_accept_head = req->dl_next;
if (queue->rskq_accept_head == NULL)
struct request_sock *req = reqsk_queue_remove(queue);
struct sock *child = req->sk;
- BUG_TRAP(child != NULL);
+ WARN_ON(child == NULL);
sk_acceptq_removed(parent);
__reqsk_free(req);
static inline int reqsk_queue_removed(struct request_sock_queue *queue,
struct request_sock *req)
{
- struct tcp_listen_opt *lopt = queue->listen_opt;
+ struct listen_sock *lopt = queue->listen_opt;
if (req->retrans == 0)
--lopt->qlen_young;
static inline int reqsk_queue_added(struct request_sock_queue *queue)
{
- struct tcp_listen_opt *lopt = queue->listen_opt;
+ struct listen_sock *lopt = queue->listen_opt;
const int prev_qlen = lopt->qlen;
lopt->qlen_young++;
return prev_qlen;
}
-static inline int reqsk_queue_len(struct request_sock_queue *queue)
+static inline int reqsk_queue_len(const struct request_sock_queue *queue)
{
return queue->listen_opt != NULL ? queue->listen_opt->qlen : 0;
}
-static inline int reqsk_queue_len_young(struct request_sock_queue *queue)
+static inline int reqsk_queue_len_young(const struct request_sock_queue *queue)
{
return queue->listen_opt->qlen_young;
}
-static inline int reqsk_queue_is_full(struct request_sock_queue *queue)
+static inline int reqsk_queue_is_full(const struct request_sock_queue *queue)
{
return queue->listen_opt->qlen >> queue->listen_opt->max_qlen_log;
}
static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
u32 hash, struct request_sock *req,
- unsigned timeout)
+ unsigned long timeout)
{
- struct tcp_listen_opt *lopt = queue->listen_opt;
+ struct listen_sock *lopt = queue->listen_opt;
req->expires = jiffies + timeout;
req->retrans = 0;