#define pr_fmt(fmt) …
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/random.h>
#include <linux/jhash.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/mm.h>
#include <linux/in.h>
#include <linux/ip.h>
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
#include <linux/ipv6.h>
#include <net/ipv6.h>
#endif
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/mutex.h>
#include <linux/kernel.h>
#include <linux/refcount.h>
#include <uapi/linux/netfilter/xt_hashlimit.h>
#define XT_HASHLIMIT_ALL …
MODULE_LICENSE(…) …;
MODULE_AUTHOR(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_ALIAS(…) …;
MODULE_ALIAS(…) …;
struct hashlimit_net { … };
static unsigned int hashlimit_net_id;
static inline struct hashlimit_net *hashlimit_pernet(struct net *net)
{ … }
static const struct seq_operations dl_seq_ops_v2;
static const struct seq_operations dl_seq_ops_v1;
static const struct seq_operations dl_seq_ops;
struct dsthash_dst { … };
struct dsthash_ent { … };
struct xt_hashlimit_htable { … };
static int
cfg_copy(struct hashlimit_cfg3 *to, const void *from, int revision)
{ … }
static DEFINE_MUTEX(hashlimit_mutex);
static struct kmem_cache *hashlimit_cachep __read_mostly;
static inline bool dst_cmp(const struct dsthash_ent *ent,
const struct dsthash_dst *b)
{ … }
static u_int32_t
hash_dst(const struct xt_hashlimit_htable *ht, const struct dsthash_dst *dst)
{ … }
static struct dsthash_ent *
dsthash_find(const struct xt_hashlimit_htable *ht,
const struct dsthash_dst *dst)
{ … }
static struct dsthash_ent *
dsthash_alloc_init(struct xt_hashlimit_htable *ht,
const struct dsthash_dst *dst, bool *race)
{ … }
static void dsthash_free_rcu(struct rcu_head *head)
{ … }
static inline void
dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent)
{ … }
static void htable_gc(struct work_struct *work);
static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg,
const char *name, u_int8_t family,
struct xt_hashlimit_htable **out_hinfo,
int revision)
{ … }
static void htable_selective_cleanup(struct xt_hashlimit_htable *ht, bool select_all)
{ … }
static void htable_gc(struct work_struct *work)
{ … }
static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo)
{ … }
static struct xt_hashlimit_htable *htable_find_get(struct net *net,
const char *name,
u_int8_t family)
{ … }
static void htable_put(struct xt_hashlimit_htable *hinfo)
{ … }
#define MAX_CPJ_v1 …
#define MAX_CPJ …
#define _POW2_BELOW2(x) …
#define _POW2_BELOW4(x) …
#define _POW2_BELOW8(x) …
#define _POW2_BELOW16(x) …
#define _POW2_BELOW32(x) …
#define _POW2_BELOW64(x) …
#define POW2_BELOW32(x) …
#define POW2_BELOW64(x) …
#define CREDITS_PER_JIFFY …
#define CREDITS_PER_JIFFY_v1 …
#define MAX_CPJ_BYTES …
#define CREDITS_PER_JIFFY_BYTES …
static u32 xt_hashlimit_len_to_chunks(u32 len)
{ … }
static u64 user2credits(u64 user, int revision)
{ … }
static u32 user2credits_byte(u32 user)
{ … }
static u64 user2rate(u64 user)
{ … }
static u64 user2rate_bytes(u32 user)
{ … }
static void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now,
u32 mode, int revision)
{ … }
static void rateinfo_init(struct dsthash_ent *dh,
struct xt_hashlimit_htable *hinfo, int revision)
{ … }
static inline __be32 maskl(__be32 a, unsigned int l)
{ … }
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
static void hashlimit_ipv6_mask(__be32 *i, unsigned int p)
{ … }
#endif
static int
hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
struct dsthash_dst *dst,
const struct sk_buff *skb, unsigned int protoff)
{ … }
static u32 hashlimit_byte_cost(unsigned int len, struct dsthash_ent *dh)
{ … }
static bool
hashlimit_mt_common(const struct sk_buff *skb, struct xt_action_param *par,
struct xt_hashlimit_htable *hinfo,
const struct hashlimit_cfg3 *cfg, int revision)
{ … }
static bool
hashlimit_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)
{ … }
static bool
hashlimit_mt_v2(const struct sk_buff *skb, struct xt_action_param *par)
{ … }
static bool
hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
{ … }
#define HASHLIMIT_MAX_SIZE …
static int hashlimit_mt_check_common(const struct xt_mtchk_param *par,
struct xt_hashlimit_htable **hinfo,
struct hashlimit_cfg3 *cfg,
const char *name, int revision)
{ … }
static int hashlimit_mt_check_v1(const struct xt_mtchk_param *par)
{ … }
static int hashlimit_mt_check_v2(const struct xt_mtchk_param *par)
{ … }
static int hashlimit_mt_check(const struct xt_mtchk_param *par)
{ … }
static void hashlimit_mt_destroy_v2(const struct xt_mtdtor_param *par)
{ … }
static void hashlimit_mt_destroy_v1(const struct xt_mtdtor_param *par)
{ … }
static void hashlimit_mt_destroy(const struct xt_mtdtor_param *par)
{ … }
static struct xt_match hashlimit_mt_reg[] __read_mostly = …;
static void *dl_seq_start(struct seq_file *s, loff_t *pos)
__acquires(htable->lock)
{ … }
static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
{ … }
static void dl_seq_stop(struct seq_file *s, void *v)
__releases(htable->lock)
{ … }
static void dl_seq_print(struct dsthash_ent *ent, u_int8_t family,
struct seq_file *s)
{ … }
static int dl_seq_real_show_v2(struct dsthash_ent *ent, u_int8_t family,
struct seq_file *s)
{ … }
static int dl_seq_real_show_v1(struct dsthash_ent *ent, u_int8_t family,
struct seq_file *s)
{ … }
static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family,
struct seq_file *s)
{ … }
static int dl_seq_show_v2(struct seq_file *s, void *v)
{ … }
static int dl_seq_show_v1(struct seq_file *s, void *v)
{ … }
static int dl_seq_show(struct seq_file *s, void *v)
{ … }
static const struct seq_operations dl_seq_ops_v1 = …;
static const struct seq_operations dl_seq_ops_v2 = …;
static const struct seq_operations dl_seq_ops = …;
static int __net_init hashlimit_proc_net_init(struct net *net)
{ … }
static void __net_exit hashlimit_proc_net_exit(struct net *net)
{ … }
static int __net_init hashlimit_net_init(struct net *net)
{ … }
static void __net_exit hashlimit_net_exit(struct net *net)
{ … }
static struct pernet_operations hashlimit_net_ops = …;
static int __init hashlimit_mt_init(void)
{ … }
static void __exit hashlimit_mt_exit(void)
{ … }
module_init(…) …;
module_exit(hashlimit_mt_exit);