Exemple #1
0
static inline int
__ipmap_create(const struct ip_set_req_ipmap_create *req,
	       struct ip_set_ipmap *map)
{
	map->netmask = req->netmask;

	if (req->netmask == 0xFFFFFFFF) {
		map->hosts = 1;
		map->sizeid = map->last_ip - map->first_ip + 1;
	} else {
		unsigned int mask_bits, netmask_bits;
		ip_set_ip_t mask;

		map->first_ip &= map->netmask;	/* Should we better bark? */

		mask = range_to_mask(map->first_ip, map->last_ip, &mask_bits);
		netmask_bits = mask_to_bits(map->netmask);

		if ((!mask && (map->first_ip || map->last_ip != 0xFFFFFFFF))
		    || netmask_bits <= mask_bits)
			return -ENOEXEC;

		DP("mask_bits %u, netmask_bits %u",
		   mask_bits, netmask_bits);
		map->hosts = 2 << (32 - netmask_bits - 1);
		map->sizeid = 2 << (netmask_bits - mask_bits - 1);
	}
	if (map->sizeid > MAX_RANGE + 1) {
		ip_set_printk("range too big, %d elements (max %d)",
			       map->sizeid, MAX_RANGE+1);
		return -ENOEXEC;
	}
	DP("hosts %u, sizeid %u", map->hosts, map->sizeid);
	return bitmap_bytes(0, map->sizeid - 1);
}
static int create(struct ip_set *set, const void *data, size_t size)
{
	int newbytes;
	struct ip_set_req_ipmap_create *req =
	    (struct ip_set_req_ipmap_create *) data;
	struct ip_set_ipmap *map;

	if (size != sizeof(struct ip_set_req_ipmap_create)) {
		ip_set_printk("data length wrong (want %zu, have %zu)",
			      sizeof(struct ip_set_req_ipmap_create),
			      size);
		return -EINVAL;
	}

	DP("from %u.%u.%u.%u to %u.%u.%u.%u",
	   HIPQUAD(req->from), HIPQUAD(req->to));

	if (req->from > req->to) {
		DP("bad ip range");
		return -ENOEXEC;
	}

	map = kmalloc(sizeof(struct ip_set_ipmap), GFP_KERNEL);
	if (!map) {
		DP("out of memory for %d bytes",
		   sizeof(struct ip_set_ipmap));
		return -ENOMEM;
	}
	map->first_ip = req->from;
	map->last_ip = req->to;
	map->netmask = req->netmask;

	if (req->netmask == 0xFFFFFFFF) {
		map->hosts = 1;
		map->sizeid = map->last_ip - map->first_ip + 1;
	} else {
		unsigned int mask_bits, netmask_bits;
		ip_set_ip_t mask;
		
		map->first_ip &= map->netmask;	/* Should we better bark? */
		
		mask = range_to_mask(map->first_ip, map->last_ip, &mask_bits);
		netmask_bits = mask_to_bits(map->netmask);
		
		if ((!mask && (map->first_ip || map->last_ip != 0xFFFFFFFF))
		    || netmask_bits <= mask_bits)
			return -ENOEXEC;

		DP("mask_bits %u, netmask_bits %u",
		   mask_bits, netmask_bits);
		map->hosts = 2 << (32 - netmask_bits - 1);
		map->sizeid = 2 << (netmask_bits - mask_bits - 1);
	}
	if (map->sizeid > MAX_RANGE + 1) {
		ip_set_printk("range too big (max %d addresses)",
			       MAX_RANGE+1);
		kfree(map);
		return -ENOEXEC;
	}
	DP("hosts %u, sizeid %u", map->hosts, map->sizeid);
	newbytes = bitmap_bytes(0, map->sizeid - 1);
	map->members = kmalloc(newbytes, GFP_KERNEL);
	if (!map->members) {
		DP("out of memory for %d bytes", newbytes);
		kfree(map);
		return -ENOMEM;
	}
	memset(map->members, 0, newbytes);
	
	set->data = map;
	return 0;
}