linux/net/netfilter/xt_hashlimit.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 *	xt_hashlimit - Netfilter module to limit the number of packets per time
 *	separately for each hashbucket (sourceip/sourceport/dstip/dstport)
 *
 *	(C) 2003-2004 by Harald Welte <[email protected]>
 *	(C) 2006-2012 Patrick McHardy <[email protected]>
 *	Copyright © CC Computer Consultants GmbH, 2007 - 2008
 *
 * Development of this code was funded by Astaro AG, http://www.astaro.com/
 */
#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)
{}

/* need to declare this at the top */
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;

/* hash table crap */
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);	/* protects htables list */
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)
{}

/* allocate dsthash_ent, initialize dst, put in htable and lock it */
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)
{}

/* The algorithm used is the Simple Token Bucket Filter (TBF)
 * see net/sched/sch_tbf.c in the linux source tree
 */

/* Rusty: This is my (non-mathematically-inclined) understanding of
   this algorithm.  The `average rate' in jiffies becomes your initial
   amount of credit `credit' and the most credit you can ever have
   `credit_cap'.  The `peak rate' becomes the cost of passing the
   test, `cost'.

   `prev' tracks the last packet hit: you gain one credit per jiffy.
   If you get credit balance more than this, the extra credit is
   discarded.  Every time the match passes, you lose `cost' credits;
   if you don't have that many, the test fails.

   See Alexey's formal explanation in net/sched/sch_tbf.c.

   To get the maximum range, we multiply by this factor (ie. you get N
   credits per jiffy).  We want to allow a rate as low as 1 per day
   (slowest userspace tool allows), which means
   CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie.
*/
#define MAX_CPJ_v1
#define MAX_CPJ

/* Repeated shift and or gives us all 1s, final shift and add 1 gives
 * us the power of 2 below the theoretical max, so GCC simply does a
 * shift. */
#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

/* in byte mode, the lowest possible rate is one packet/second.
 * credit_cap is used as a counter that tells us how many times we can
 * refill the "credits available" counter when it becomes empty.
 */
#define MAX_CPJ_BYTES
#define CREDITS_PER_JIFFY_BYTES

static u32 xt_hashlimit_len_to_chunks(u32 len)
{}

/* Precision saver. */
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 =;

/* PROC stuff */
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);