#define pr_fmt(fmt) …
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/jhash.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/rbtree.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/netfilter/nf_conntrack_tcp.h>
#include <linux/netfilter/x_tables.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_count.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_tuple.h>
#include <net/netfilter/nf_conntrack_zones.h>
#define CONNCOUNT_SLOTS …
#define CONNCOUNT_GC_MAX_NODES …
#define MAX_KEYLEN …
struct nf_conncount_tuple { … };
struct nf_conncount_rb { … };
static spinlock_t nf_conncount_locks[CONNCOUNT_SLOTS] __cacheline_aligned_in_smp;
struct nf_conncount_data { … };
static u_int32_t conncount_rnd __read_mostly;
static struct kmem_cache *conncount_rb_cachep __read_mostly;
static struct kmem_cache *conncount_conn_cachep __read_mostly;
static inline bool already_closed(const struct nf_conn *conn)
{ … }
static int key_diff(const u32 *a, const u32 *b, unsigned int klen)
{ … }
static void conn_free(struct nf_conncount_list *list,
struct nf_conncount_tuple *conn)
{ … }
static const struct nf_conntrack_tuple_hash *
find_or_evict(struct net *net, struct nf_conncount_list *list,
struct nf_conncount_tuple *conn)
{ … }
static int __nf_conncount_add(struct net *net,
struct nf_conncount_list *list,
const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_zone *zone)
{ … }
int nf_conncount_add(struct net *net,
struct nf_conncount_list *list,
const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_zone *zone)
{ … }
EXPORT_SYMBOL_GPL(…);
void nf_conncount_list_init(struct nf_conncount_list *list)
{ … }
EXPORT_SYMBOL_GPL(…);
bool nf_conncount_gc_list(struct net *net,
struct nf_conncount_list *list)
{ … }
EXPORT_SYMBOL_GPL(…);
static void __tree_nodes_free(struct rcu_head *h)
{ … }
static void tree_nodes_free(struct rb_root *root,
struct nf_conncount_rb *gc_nodes[],
unsigned int gc_count)
{ … }
static void schedule_gc_worker(struct nf_conncount_data *data, int tree)
{ … }
static unsigned int
insert_tree(struct net *net,
struct nf_conncount_data *data,
struct rb_root *root,
unsigned int hash,
const u32 *key,
const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_zone *zone)
{ … }
static unsigned int
count_tree(struct net *net,
struct nf_conncount_data *data,
const u32 *key,
const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_zone *zone)
{ … }
static void tree_gc_worker(struct work_struct *work)
{ … }
unsigned int nf_conncount_count(struct net *net,
struct nf_conncount_data *data,
const u32 *key,
const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_zone *zone)
{ … }
EXPORT_SYMBOL_GPL(…);
struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
unsigned int keylen)
{ … }
EXPORT_SYMBOL_GPL(…);
void nf_conncount_cache_free(struct nf_conncount_list *list)
{ … }
EXPORT_SYMBOL_GPL(…);
static void destroy_tree(struct rb_root *r)
{ … }
void nf_conncount_destroy(struct net *net, unsigned int family,
struct nf_conncount_data *data)
{ … }
EXPORT_SYMBOL_GPL(…);
static int __init nf_conncount_modinit(void)
{ … }
static void __exit nf_conncount_modexit(void)
{ … }
module_init(…) …;
module_exit(nf_conncount_modexit);
MODULE_AUTHOR(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;