⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 130-netfilter_ipset.patch

📁 Linux Home Server 是专门为家庭和SOHO/SMB 设计的高性价比的ISCSI 存储服务器, 具有如下的特色: 强大的iscsi 存储服务器软件; 混合iscsi 和NAS 服务;
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
+		goto undo;+	memset(harray->arrays[i], 0, (hashsize - i * max_elements) * typesize);++	harray->max_elements = max_elements;+	harray->arrays[size] = NULL;+	+	return (void *)harray;++    undo:+    	for (j = 0; j < i; j++) {+    		kfree(harray->arrays[j]);+    	}+    	kfree(harray);+    	return NULL;+}++static inline void harray_free(void *h)+{+	struct harray *harray = (struct harray *) h;+	size_t i;+	+    	for (i = 0; harray->arrays[i] != NULL; i++)+    		kfree(harray->arrays[i]);+    	kfree(harray);+}++static inline void harray_flush(void *h, size_t hashsize, size_t typesize)+{+	struct harray *harray = (struct harray *) h;+	size_t i;+	+    	for (i = 0; harray->arrays[i+1] != NULL; i++)+		memset(harray->arrays[i], 0, harray->max_elements * typesize);+	memset(harray->arrays[i], 0, +	       (hashsize - i * harray->max_elements) * typesize);+}++#define HARRAY_ELEM(h, type, which)				\+({								\+	struct harray *__h = (struct harray *)(h);		\+	((type)((__h)->arrays[(which)/(__h)->max_elements])	\+		+ (which)%(__h)->max_elements);			\+})++#endif				/* __KERNEL__ */++#endif /*_IP_SET_MALLOC_H*/Index: linux-2.6.21.7/include/linux/netfilter_ipv4/ip_set_nethash.h===================================================================--- /dev/null+++ linux-2.6.21.7/include/linux/netfilter_ipv4/ip_set_nethash.h@@ -0,0 +1,55 @@+#ifndef __IP_SET_NETHASH_H+#define __IP_SET_NETHASH_H++#include <linux/netfilter_ipv4/ip_set.h>++#define SETTYPE_NAME "nethash"+#define MAX_RANGE 0x0000FFFF++struct ip_set_nethash {+	ip_set_ip_t *members;		/* the nethash proper */+	uint32_t elements;		/* number of elements */+	uint32_t hashsize;		/* hash size */+	uint16_t probes;		/* max number of probes  */+	uint16_t resize;		/* resize factor in percent */+	unsigned char cidr[30];		/* CIDR sizes */+	void *initval[0];		/* initvals for jhash_1word */+};++struct ip_set_req_nethash_create {+	uint32_t hashsize;+	uint16_t probes;+	uint16_t resize;+};++struct ip_set_req_nethash {+	ip_set_ip_t ip;+	unsigned char cidr;+};++static unsigned char shifts[] = {255, 253, 249, 241, 225, 193, 129, 1};++static inline ip_set_ip_t +pack(ip_set_ip_t ip, unsigned char cidr)+{+	ip_set_ip_t addr, *paddr = &addr;+	unsigned char n, t, *a;++	addr = htonl(ip & (0xFFFFFFFF << (32 - (cidr))));+#ifdef __KERNEL__+	DP("ip:%u.%u.%u.%u/%u", NIPQUAD(addr), cidr);+#endif+	n = cidr / 8;+	t = cidr % 8;	+	a = &((unsigned char *)paddr)[n];+	*a = *a /(1 << (8 - t)) + shifts[t];+#ifdef __KERNEL__+	DP("n: %u, t: %u, a: %u", n, t, *a);+	DP("ip:%u.%u.%u.%u/%u, %u.%u.%u.%u",+	   HIPQUAD(ip), cidr, NIPQUAD(addr));+#endif++	return ntohl(addr);+}++#endif	/* __IP_SET_NETHASH_H */Index: linux-2.6.21.7/include/linux/netfilter_ipv4/ip_set_portmap.h===================================================================--- /dev/null+++ linux-2.6.21.7/include/linux/netfilter_ipv4/ip_set_portmap.h@@ -0,0 +1,25 @@+#ifndef __IP_SET_PORTMAP_H+#define __IP_SET_PORTMAP_H++#include <linux/netfilter_ipv4/ip_set.h>++#define SETTYPE_NAME	"portmap"+#define MAX_RANGE	0x0000FFFF+#define INVALID_PORT	(MAX_RANGE + 1)++struct ip_set_portmap {+	void *members;			/* the portmap proper */+	ip_set_ip_t first_port;		/* host byte order, included in range */+	ip_set_ip_t last_port;		/* host byte order, included in range */+};++struct ip_set_req_portmap_create {+	ip_set_ip_t from;+	ip_set_ip_t to;+};++struct ip_set_req_portmap {+	ip_set_ip_t port;+};++#endif /* __IP_SET_PORTMAP_H */Index: linux-2.6.21.7/include/linux/netfilter_ipv4/ipt_set.h===================================================================--- /dev/null+++ linux-2.6.21.7/include/linux/netfilter_ipv4/ipt_set.h@@ -0,0 +1,21 @@+#ifndef _IPT_SET_H+#define _IPT_SET_H++#include <linux/netfilter_ipv4/ip_set.h>++struct ipt_set_info {+	ip_set_id_t index;+	u_int32_t flags[IP_SET_MAX_BINDINGS + 1];+};++/* match info */+struct ipt_set_info_match {+	struct ipt_set_info match_set;+};++struct ipt_set_info_target {+	struct ipt_set_info add_set;+	struct ipt_set_info del_set;+};++#endif /*_IPT_SET_H*/Index: linux-2.6.21.7/net/ipv4/netfilter/ip_set.c===================================================================--- /dev/null+++ linux-2.6.21.7/net/ipv4/netfilter/ip_set.c@@ -0,0 +1,2003 @@+/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>+ *                         Patrick Schaaf <bof@bof.de>+ * Copyright (C) 2003-2004 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License version 2 as+ * published by the Free Software Foundation.  + */++/* Kernel module for IP set management */++#include <linux/version.h>+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/moduleparam.h>+#include <linux/kmod.h>+#include <linux/ip.h>+#include <linux/skbuff.h>+#include <linux/random.h>+#include <linux/jhash.h>+#include <linux/netfilter_ipv4/ip_tables.h>+#include <linux/errno.h>+#include <asm/uaccess.h>+#include <asm/bitops.h>+#include <asm/semaphore.h>+#include <linux/spinlock.h>+#include <linux/vmalloc.h>++#define ASSERT_READ_LOCK(x)+#define ASSERT_WRITE_LOCK(x)+#include <linux/netfilter_ipv4/ip_set.h>++static struct list_head set_type_list;		/* all registered sets */+static struct ip_set **ip_set_list;		/* all individual sets */+static DEFINE_RWLOCK(ip_set_lock);		/* protects the lists and the hash */+static DECLARE_MUTEX(ip_set_app_mutex);		/* serializes user access */+static ip_set_id_t ip_set_max = CONFIG_IP_NF_SET_MAX;+static ip_set_id_t ip_set_bindings_hash_size =  CONFIG_IP_NF_SET_HASHSIZE;+static struct list_head *ip_set_hash;		/* hash of bindings */+static unsigned int ip_set_hash_random;		/* random seed */++/*+ * Sets are identified either by the index in ip_set_list or by id.+ * The id never changes and is used to find a key in the hash. + * The index may change by swapping and used at all other places + * (set/SET netfilter modules, binding value, etc.)+ *+ * Userspace requests are serialized by ip_set_mutex and sets can+ * be deleted only from userspace. Therefore ip_set_list locking + * must obey the following rules:+ *+ * - kernel requests: read and write locking mandatory+ * - user requests: read locking optional, write locking mandatory+ */++static inline void+__ip_set_get(ip_set_id_t index)+{+	atomic_inc(&ip_set_list[index]->ref);+}++static inline void+__ip_set_put(ip_set_id_t index)+{+	atomic_dec(&ip_set_list[index]->ref);+}++/*+ * Binding routines+ */++static inline struct ip_set_hash *+__ip_set_find(u_int32_t key, ip_set_id_t id, ip_set_ip_t ip)+{+	struct ip_set_hash *set_hash;++	list_for_each_entry(set_hash, &ip_set_hash[key], list)+		if (set_hash->id == id && set_hash->ip == ip)+			return set_hash;+			+	return NULL;+}++static ip_set_id_t+ip_set_find_in_hash(ip_set_id_t id, ip_set_ip_t ip)+{+	u_int32_t key = jhash_2words(id, ip, ip_set_hash_random) +				% ip_set_bindings_hash_size;+	struct ip_set_hash *set_hash;++	ASSERT_READ_LOCK(&ip_set_lock);+	IP_SET_ASSERT(ip_set_list[id]);+	DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip));	+	+	set_hash = __ip_set_find(key, id, ip);+	+	DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name, +	   HIPQUAD(ip),+	   set_hash != NULL ? ip_set_list[set_hash->binding]->name : "");++	return (set_hash != NULL ? set_hash->binding : IP_SET_INVALID_ID);+}++static inline void +__set_hash_del(struct ip_set_hash *set_hash)+{+	ASSERT_WRITE_LOCK(&ip_set_lock);+	IP_SET_ASSERT(ip_set_list[set_hash->binding]);	++	__ip_set_put(set_hash->binding);+	list_del(&set_hash->list);+	kfree(set_hash);+}++static int+ip_set_hash_del(ip_set_id_t id, ip_set_ip_t ip)+{+	u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)+				% ip_set_bindings_hash_size;+	struct ip_set_hash *set_hash;+	+	IP_SET_ASSERT(ip_set_list[id]);+	DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip));	+	write_lock_bh(&ip_set_lock);+	set_hash = __ip_set_find(key, id, ip);+	DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,+	   HIPQUAD(ip),+	   set_hash != NULL ? ip_set_list[set_hash->binding]->name : "");++	if (set_hash != NULL)+		__set_hash_del(set_hash);+	write_unlock_bh(&ip_set_lock);+	return 0;+}++static int +ip_set_hash_add(ip_set_id_t id, ip_set_ip_t ip, ip_set_id_t binding)+{+	u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)+				% ip_set_bindings_hash_size;+	struct ip_set_hash *set_hash;+	int ret = 0;+	+	IP_SET_ASSERT(ip_set_list[id]);+	IP_SET_ASSERT(ip_set_list[binding]);+	DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name, +	   HIPQUAD(ip), ip_set_list[binding]->name);+	write_lock_bh(&ip_set_lock);+	set_hash = __ip_set_find(key, id, ip);+	if (!set_hash) {+		set_hash = kmalloc(sizeof(struct ip_set_hash), GFP_ATOMIC);+		if (!set_hash) {+			ret = -ENOMEM;+			goto unlock;+		}+		INIT_LIST_HEAD(&set_hash->list);+		set_hash->id = id;+		set_hash->ip = ip;+		list_add(&set_hash->list, &ip_set_hash[key]);+	} else {+		IP_SET_ASSERT(ip_set_list[set_hash->binding]);	+		DP("overwrite binding: %s",+		   ip_set_list[set_hash->binding]->name);+		__ip_set_put(set_hash->binding);+	}+	set_hash->binding = binding;+	__ip_set_get(set_hash->binding);+	DP("stored: key %u, id %u (%s), ip %u.%u.%u.%u, binding %u (%s)",+	   key, id, ip_set_list[id]->name,+	   HIPQUAD(ip), binding, ip_set_list[binding]->name);+    unlock:+	write_unlock_bh(&ip_set_lock);+	return ret;+}++#define FOREACH_HASH_DO(fn, args...) 						\+({										\+	ip_set_id_t __key;							\+	struct ip_set_hash *__set_hash;						\+										\+	for (__key = 0; __key < ip_set_bindings_hash_size; __key++) {		\+		list_for_each_entry(__set_hash, &ip_set_hash[__key], list)	\+			fn(__set_hash , ## args);				\+	}									\+})++#define FOREACH_HASH_RW_DO(fn, args...) 						\+({										\+	ip_set_id_t __key;							\+	struct ip_set_hash *__set_hash, *__n;					\+										\+	ASSERT_WRITE_LOCK(&ip_set_lock);					\+	for (__key = 0; __key < ip_set_bindings_hash_size; __key++) {		\+		list_for_each_entry_safe(__set_hash, __n, &ip_set_hash[__key], list)\+			fn(__set_hash , ## args);				\+	}									\+})++/* Add, del and test set entries from kernel */++#define follow_bindings(index, set, ip)					\+((index = ip_set_find_in_hash((set)->id, ip)) != IP_SET_INVALID_ID	\+ || (index = (set)->binding) != IP_SET_INVALID_ID)++int+ip_set_testip_kernel(ip_set_id_t index,+		     const struct sk_buff *skb,+		     const u_int32_t *flags)+{+	struct ip_set *set;+	ip_set_ip_t ip;+	int res;+	unsigned char i = 0;+	+	IP_SET_ASSERT(flags[i]);+	read_lock_bh(&ip_set_lock);+	do {+		set = ip_set_list[index];+		IP_SET_ASSERT(set);+		DP("set %s, index %u", set->name, index);+		read_lock_bh(&set->lock);+		res = set->type->testip_kernel(set, skb, &ip, flags, i++);+		read_unlock_bh(&set->lock);+		i += !!(set->type->features & IPSET_DATA_DOUBLE);+	} while (res > 0 +		 && flags[i] +		 && follow_bindings(index, set, ip));+	read_unlock_bh(&ip_set_lock);++	return res;+}++void+ip_set_addip_kernel(ip_set_id_t index,+		    const struct sk_buff *skb,+		    const u_int32_t *flags)+{+	struct ip_set *set;+	ip_set_ip_t ip;+	int res;+	unsigned char i = 0;++	IP_SET_ASSERT(flags[i]);+   retry:+	read_lock_bh(&ip_set_lock);+	do {+		set = ip_set_list[index];+		IP_SET_ASSERT(set);+		DP("set %s, index %u", set->name, index);+		write_lock_bh(&set->lock);+		res = set->type->addip_kernel(set, skb, &ip, flags, i++);+		write_unlock_bh(&set->lock);+		i += !!(set->type->features & IPSET_DATA_DOUBLE);+	} while ((res == 0 || res == -EEXIST)+		 && flags[i] +		 && follow_bindings(index, set, ip));+	read_unlock_bh(&ip_set_lock);++	if (res == -EAGAIN+	    && set->type->retry+	    && (res = set->type->retry(set)) == 0)+	    	goto retry;+}++void+ip_set_delip_kernel(ip_set_id_t index,+		    const struct sk_buff *skb,+		    const u_int32_t *flags)+{+	struct ip_set *set;+	ip_set_ip_t ip;+	int res;+	unsigned char i = 0;++	IP_SET_ASSERT(flags[i]);+	read_lock_bh(&ip_set_lock);+	do {+		set = ip_set_list[index];+		IP_SET_ASSERT(set);+		DP("set %s, index %u", set->name, index);+		write_lock_bh(&set->lock);+		res = set->type->delip_kernel(set, skb, &ip, flags, i++);+		write_unlock_bh(&set->lock);+		i += !!(set->type->features & IPSET_DATA_DOUBLE);+	} while ((res == 0 || res == -EEXIST)+		 && flags[i] +		 && follow_bindings(index, set, ip));+	read_unlock_bh(&ip_set_lock);+}++/* Register and deregister settype */++static inline struct ip_set_type *+find_set_type(const char *name)+{+	struct ip_set_type *set_type;++	list_for_each_entry(set_type, &set_type_list, list)+		if (!strncmp(set_type->typename, name, IP_SET_MAXNAMELEN - 1))+			return set_type;+	return NULL;+}++int +ip_set_register_set_type(struct ip_set_type *set_type)+{+	int ret = 0;+	+	if (set_type->protocol_version != IP_SET_PROTOCOL_VERSION) {+		ip_set_printk("'%s' uses wrong protocol version %u (want %u)",+			      set_type->typename,+			      set_type->protocol_version,+			      IP_SET_PROTOCOL_VERSION);+		return -EINVAL;+	}++	write_lock_bh(&ip_set_lock);+	if (find_set_type(set_type->typename)) {+		/* Duplicate! */+		ip_set_printk("'%s' already registered!", +			      set_type->typename);+		ret = -EINVAL;+		goto unlock;+	}+	if (!try_module_get(THIS_MODULE)) {+		ret = -EFAULT;+		goto unlock;+	}+	list_add(&set_type->list, &set_type_list);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -