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

📄 130-netfilter_ipset.patch

📁 Linux Home Server 是专门为家庭和SOHO/SMB 设计的高性价比的ISCSI 存储服务器, 具有如下的特色: 强大的iscsi 存储服务器软件; 混合iscsi 和NAS 服务;
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
+		strcpy(modulename, "ip_set_");+		strcat(modulename, typename);+		DP("try to load %s", modulename);+		request_module(modulename);+		set->type = find_set_type_rlock(typename);+	}+	if (set->type == NULL) {+		ip_set_printk("no set type '%s', set '%s' not created",+			      typename, name);+		res = -ENOENT;+		goto out;+	}+	if (!try_module_get(set->type->me)) {+		read_unlock_bh(&ip_set_lock);+		res = -EFAULT;+		goto out;+	}+	read_unlock_bh(&ip_set_lock);++	/*+	 * Without holding any locks, create private part.+	 */+	res = set->type->create(set, data, size);+	if (res != 0)+		goto put_out;++	/* BTW, res==0 here. */++	/*+	 * Here, we have a valid, constructed set. &ip_set_lock again,+	 * find free id/index and check that it is not already in +	 * ip_set_list.+	 */+	write_lock_bh(&ip_set_lock);+	if ((res = find_free_id(set->name, &index, &id)) != 0) {+		DP("no free id!");+		goto cleanup;+	}++	/* Make sure restore gets the same index */+	if (restore != IP_SET_INVALID_ID && index != restore) {+		DP("Can't restore, sets are screwed up");+		res = -ERANGE;+		goto cleanup;+	}+	 +	/*+	 * Finally! Add our shiny new set to the list, and be done.+	 */+	DP("create: '%s' created with index %u, id %u!", set->name, index, id);+	set->id = id;+	ip_set_list[index] = set;+	write_unlock_bh(&ip_set_lock);+	return res;+	+    cleanup:+	write_unlock_bh(&ip_set_lock);+	set->type->destroy(set);+    put_out:+	module_put(set->type->me);+    out:+	kfree(set);+	return res;+}++/*+ * Destroy a given existing set+ */+static void+ip_set_destroy_set(ip_set_id_t index)+{+	struct ip_set *set = ip_set_list[index];++	IP_SET_ASSERT(set);+	DP("set: %s",  set->name);+	write_lock_bh(&ip_set_lock);+	FOREACH_HASH_RW_DO(__set_hash_del_byid, set->id);+	if (set->binding != IP_SET_INVALID_ID)+		__ip_set_put(set->binding);+	ip_set_list[index] = NULL;+	write_unlock_bh(&ip_set_lock);++	/* Must call it without holding any lock */+	set->type->destroy(set);+	module_put(set->type->me);+	kfree(set);+}++/*+ * Destroy a set - or all sets+ * Sets must not be referenced/used.+ */+static int+ip_set_destroy(ip_set_id_t index)+{+	ip_set_id_t i;++	/* ref modification always protected by the mutex */+	if (index != IP_SET_INVALID_ID) {+		if (atomic_read(&ip_set_list[index]->ref))+			return -EBUSY;+		ip_set_destroy_set(index);+	} else {+		for (i = 0; i < ip_set_max; i++) {+			if (ip_set_list[i] != NULL +			    && (atomic_read(&ip_set_list[i]->ref)))+			    	return -EBUSY;+		}++		for (i = 0; i < ip_set_max; i++) {+			if (ip_set_list[i] != NULL)+				ip_set_destroy_set(i);+		}+	}+	return 0;+}++static void+ip_set_flush_set(struct ip_set *set)+{+	DP("set: %s %u",  set->name, set->id);++	write_lock_bh(&set->lock);+	set->type->flush(set);+	write_unlock_bh(&set->lock);+}++/* + * Flush data in a set - or in all sets+ */+static int+ip_set_flush(ip_set_id_t index)+{+	if (index != IP_SET_INVALID_ID) {+		IP_SET_ASSERT(ip_set_list[index]);+		ip_set_flush_set(ip_set_list[index]);+	} else+		FOREACH_SET_DO(ip_set_flush_set);++	return 0;+}++/* Rename a set */+static int+ip_set_rename(ip_set_id_t index, const char *name)+{+	struct ip_set *set = ip_set_list[index];+	ip_set_id_t i;+	int res = 0;++	DP("set: %s to %s",  set->name, name);+	write_lock_bh(&ip_set_lock);+	for (i = 0; i < ip_set_max; i++) {+		if (ip_set_list[i] != NULL+		    && strncmp(ip_set_list[i]->name, +			       name,+			       IP_SET_MAXNAMELEN - 1) == 0) {+			res = -EEXIST;+			goto unlock;+		}+	}+	strncpy(set->name, name, IP_SET_MAXNAMELEN);+    unlock:+	write_unlock_bh(&ip_set_lock);+	return res;+}++/*+ * Swap two sets so that name/index points to the other.+ * References are also swapped.+ */+static int+ip_set_swap(ip_set_id_t from_index, ip_set_id_t to_index)+{+	struct ip_set *from = ip_set_list[from_index];+	struct ip_set *to = ip_set_list[to_index];+	char from_name[IP_SET_MAXNAMELEN];+	u_int32_t from_ref;++	DP("set: %s to %s",  from->name, to->name);+	/* Features must not change. Artifical restriction. */+	if (from->type->features != to->type->features)+		return -ENOEXEC;++	/* No magic here: ref munging protected by the mutex */	+	write_lock_bh(&ip_set_lock);+	strncpy(from_name, from->name, IP_SET_MAXNAMELEN);+	from_ref = atomic_read(&from->ref);++	strncpy(from->name, to->name, IP_SET_MAXNAMELEN);+	atomic_set(&from->ref, atomic_read(&to->ref));+	strncpy(to->name, from_name, IP_SET_MAXNAMELEN);+	atomic_set(&to->ref, from_ref);+	+	ip_set_list[from_index] = to;+	ip_set_list[to_index] = from;+	+	write_unlock_bh(&ip_set_lock);+	return 0;+}++/*+ * List set data+ */++static inline void+__set_hash_bindings_size_list(struct ip_set_hash *set_hash,+			      ip_set_id_t id, size_t *size)+{+	if (set_hash->id == id)+		*size += sizeof(struct ip_set_hash_list);+}++static inline void+__set_hash_bindings_size_save(struct ip_set_hash *set_hash,+			      ip_set_id_t id, size_t *size)+{+	if (set_hash->id == id)+		*size += sizeof(struct ip_set_hash_save);+}++static inline void+__set_hash_bindings(struct ip_set_hash *set_hash,+		    ip_set_id_t id, void *data, int *used)+{+	if (set_hash->id == id) {+		struct ip_set_hash_list *hash_list = +			(struct ip_set_hash_list *)(data + *used);++		hash_list->ip = set_hash->ip;+		hash_list->binding = set_hash->binding;+		*used += sizeof(struct ip_set_hash_list);+	}+}++static int ip_set_list_set(ip_set_id_t index,+			   void *data,+			   int *used,+			   int len)+{+	struct ip_set *set = ip_set_list[index];+	struct ip_set_list *set_list;++	/* Pointer to our header */+	set_list = (struct ip_set_list *) (data + *used);++	DP("set: %s, used: %d %p %p", set->name, *used, data, data + *used);++	/* Get and ensure header size */+	if (*used + sizeof(struct ip_set_list) > len)+		goto not_enough_mem;+	*used += sizeof(struct ip_set_list);++	read_lock_bh(&set->lock);+	/* Get and ensure set specific header size */+	set_list->header_size = set->type->header_size;+	if (*used + set_list->header_size > len)+		goto unlock_set;++	/* Fill in the header */+	set_list->index = index;+	set_list->binding = set->binding;+	set_list->ref = atomic_read(&set->ref);++	/* Fill in set spefific header data */+	set->type->list_header(set, data + *used);+	*used += set_list->header_size;++	/* Get and ensure set specific members size */+	set_list->members_size = set->type->list_members_size(set);+	if (*used + set_list->members_size > len)+		goto unlock_set;++	/* Fill in set spefific members data */+	set->type->list_members(set, data + *used);+	*used += set_list->members_size;+	read_unlock_bh(&set->lock);++	/* Bindings */++	/* Get and ensure set specific bindings size */+	set_list->bindings_size = 0;+	FOREACH_HASH_DO(__set_hash_bindings_size_list,+			set->id, &set_list->bindings_size);+	if (*used + set_list->bindings_size > len)+		goto not_enough_mem;++	/* Fill in set spefific bindings data */+	FOREACH_HASH_DO(__set_hash_bindings, set->id, data, used);+	+	return 0;++    unlock_set:+	read_unlock_bh(&set->lock);+    not_enough_mem:+	DP("not enough mem, try again");+	return -EAGAIN;+}++/*+ * Save sets+ */+static int ip_set_save_set(ip_set_id_t index,+			   void *data,+			   int *used,+			   int len)+{+	struct ip_set *set;+	struct ip_set_save *set_save;++	/* Pointer to our header */+	set_save = (struct ip_set_save *) (data + *used);++	/* Get and ensure header size */+	if (*used + sizeof(struct ip_set_save) > len)+		goto not_enough_mem;+	*used += sizeof(struct ip_set_save);++	set = ip_set_list[index];+	DP("set: %s, used: %u(%u) %p %p", set->name, *used, len, +	   data, data + *used);++	read_lock_bh(&set->lock);+	/* Get and ensure set specific header size */+	set_save->header_size = set->type->header_size;+	if (*used + set_save->header_size > len)+		goto unlock_set;++	/* Fill in the header */+	set_save->index = index;+	set_save->binding = set->binding;++	/* Fill in set spefific header data */+	set->type->list_header(set, data + *used);+	*used += set_save->header_size;++	DP("set header filled: %s, used: %u(%u) %p %p", set->name, *used,+	   set_save->header_size, data, data + *used);+	/* Get and ensure set specific members size */+	set_save->members_size = set->type->list_members_size(set);+	if (*used + set_save->members_size > len)+		goto unlock_set;++	/* Fill in set spefific members data */+	set->type->list_members(set, data + *used);+	*used += set_save->members_size;+	read_unlock_bh(&set->lock);+	DP("set members filled: %s, used: %u(%u) %p %p", set->name, *used,+	   set_save->members_size, data, data + *used);+	return 0;++    unlock_set:+	read_unlock_bh(&set->lock);+    not_enough_mem:+	DP("not enough mem, try again");+	return -EAGAIN;+}++static inline void+__set_hash_save_bindings(struct ip_set_hash *set_hash,+			 ip_set_id_t id,+			 void *data,+			 int *used,+			 int len,+			 int *res)+{+	if (*res == 0+	    && (id == IP_SET_INVALID_ID || set_hash->id == id)) {+		struct ip_set_hash_save *hash_save = +			(struct ip_set_hash_save *)(data + *used);+		/* Ensure bindings size */+		if (*used + sizeof(struct ip_set_hash_save) > len) {+			*res = -ENOMEM;+			return;+		}+		hash_save->id = set_hash->id;+		hash_save->ip = set_hash->ip;+		hash_save->binding = set_hash->binding;+		*used += sizeof(struct ip_set_hash_save);+	}+}++static int ip_set_save_bindings(ip_set_id_t index,+			   	void *data,+			   	int *used,+			   	int len)+{+	int res = 0;+	struct ip_set_save *set_save;++	DP("used %u, len %u", *used, len);+	/* Get and ensure header size */+	if (*used + sizeof(struct ip_set_save) > len)+		return -ENOMEM;++	/* Marker */+	set_save = (struct ip_set_save *) (data + *used);+	set_save->index = IP_SET_INVALID_ID;+	set_save->header_size = 0;+	set_save->members_size = 0;+	*used += sizeof(struct ip_set_save);++	DP("marker added used %u, len %u", *used, len);+	/* Fill in bindings data */+	if (index != IP_SET_INVALID_ID)+		/* Sets are identified by id in hash */+		index = ip_set_list[index]->id;+	FOREACH_HASH_DO(__set_hash_save_bindings, index, data, used, len, &res);++	return res;	+}++/*+ * Restore sets+ */+static int ip_set_restore(void *data,+			  int len)+{+	int res = 0;+	int line = 0, used = 0, members_size;+	struct ip_set *set;+	struct ip_set_hash_save *hash_save;+	struct ip_set_restore *set_restore;+	ip_set_id_t index;++	/* Loop to restore sets */+	while (1) {+		line++;+		+		DP("%u %u %u", used, sizeof(struct ip_set_restore), len);+		/* Get and ensure header size */+		if (used + sizeof(struct ip_set_restore) > len)+			return line;+		set_restore = (struct ip_set_restore *) (data + used);+		used += sizeof(struct ip_set_restore);++		/* Ensure data size */+		if (used +		    + set_restore->header_size +		    + set_restore->members_size > len)+			return line;++		/* Check marker */+		if (set_restore->index == IP_SET_INVALID_ID) {+			line--;+			goto bindings;+		}+		+		/* Try to create the set */+		DP("restore %s %s", set_restore->name, set_restore->typename);+		res = ip_set_create(set_restore->name,+				    set_restore->typename,+				    set_restore->index,+				    data + used,+				    set_restore->header_size);+		+		if (res != 0)+			return line;+		used += set_restore->header_size;++		index = ip_set_find_byindex(set_restore->index);+		DP("index %u, restore_index %u", index, set_restore->index);+		if (index != set_restore->index)+			return line;+		/* Try to restore members data */+		set = ip_set_list[index];+		members_size = 0;+		DP("members_size %u reqsize %u",+		   set_restore->members_size, set->type->reqsize);+		while (members_size + set->type->reqsize <=+		       set_restore->members_size) {+			line++;+		       	DP("members: %u, line %u", members_size, line);+			res = __ip_set_addip(index,+					   data + used + members_size,+					   set->type->reqsize);+			if (!(res == 0 || res == -EEXIST)) +				return line;+			members_size += set->type->reqsize;+		}++		DP("members_size %u  %u",+		   set_restore->members_size, members_size);+		if (members_size != set_restore->members_size)+			return line++;+		used += set_restore->members_size;		+	}+	+   bindings:+   	/* Loop to restore bindings */+   	while (used < len) {+		line++;++		DP("restore binding, line %u", line);		+		/* Get and ensure size */+		if (used + sizeof(struct ip_set_hash_save) > len)+			

⌨️ 快捷键说明

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