1 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2  *                         Patrick Schaaf <bof@bof.de>
3  * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  */
9 
10 /* Kernel module implementing an IP set type: the bitmap:ip type */
11 
12 #include <linux/module.h>
13 #include <linux/ip.h>
14 #include <linux/skbuff.h>
15 #include <linux/errno.h>
16 #include <linux/bitops.h>
17 #include <linux/spinlock.h>
18 #include <linux/netlink.h>
19 #include <linux/jiffies.h>
20 #include <linux/timer.h>
21 #include <net/netlink.h>
22 #include <net/tcp.h>
23 
24 #include <linux/netfilter/ipset/pfxlen.h>
25 #include <linux/netfilter/ipset/ip_set.h>
26 #include <linux/netfilter/ipset/ip_set_bitmap.h>
27 
28 #define IPSET_TYPE_REV_MIN	0
29 /*				1	   Counter support added */
30 #define IPSET_TYPE_REV_MAX	2	/* Comment support added */
31 
32 MODULE_LICENSE("GPL");
33 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
34 IP_SET_MODULE_DESC("bitmap:ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
35 MODULE_ALIAS("ip_set_bitmap:ip");
36 
37 #define MTYPE		bitmap_ip
38 
39 /* Type structure */
40 struct bitmap_ip {
41 	void *members;		/* the set members */
42 	void *extensions;	/* data extensions */
43 	u32 first_ip;		/* host byte order, included in range */
44 	u32 last_ip;		/* host byte order, included in range */
45 	u32 elements;		/* number of max elements in the set */
46 	u32 hosts;		/* number of hosts in a subnet */
47 	size_t memsize;		/* members size */
48 	u8 netmask;		/* subnet netmask */
49 	struct timer_list gc;	/* garbage collection */
50 };
51 
52 /* ADT structure for generic function args */
53 struct bitmap_ip_adt_elem {
54 	u16 id;
55 };
56 
57 static inline u32
58 ip_to_id(const struct bitmap_ip *m, u32 ip)
59 {
60 	return ((ip & ip_set_hostmask(m->netmask)) - m->first_ip)/m->hosts;
61 }
62 
63 /* Common functions */
64 
65 static inline int
66 bitmap_ip_do_test(const struct bitmap_ip_adt_elem *e,
67 		  struct bitmap_ip *map, size_t dsize)
68 {
69 	return !!test_bit(e->id, map->members);
70 }
71 
72 static inline int
73 bitmap_ip_gc_test(u16 id, const struct bitmap_ip *map, size_t dsize)
74 {
75 	return !!test_bit(id, map->members);
76 }
77 
78 static inline int
79 bitmap_ip_do_add(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map,
80 		 u32 flags, size_t dsize)
81 {
82 	return !!test_and_set_bit(e->id, map->members);
83 }
84 
85 static inline int
86 bitmap_ip_do_del(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map)
87 {
88 	return !test_and_clear_bit(e->id, map->members);
89 }
90 
91 static inline int
92 bitmap_ip_do_list(struct sk_buff *skb, const struct bitmap_ip *map, u32 id,
93 		  size_t dsize)
94 {
95 	return nla_put_ipaddr4(skb, IPSET_ATTR_IP,
96 			htonl(map->first_ip + id * map->hosts));
97 }
98 
99 static inline int
100 bitmap_ip_do_head(struct sk_buff *skb, const struct bitmap_ip *map)
101 {
102 	return nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip)) ||
103 	       nla_put_ipaddr4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)) ||
104 	       (map->netmask != 32 &&
105 		nla_put_u8(skb, IPSET_ATTR_NETMASK, map->netmask));
106 }
107 
108 static int
109 bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
110 	       const struct xt_action_param *par,
111 	       enum ipset_adt adt, struct ip_set_adt_opt *opt)
112 {
113 	struct bitmap_ip *map = set->data;
114 	ipset_adtfn adtfn = set->variant->adt[adt];
115 	struct bitmap_ip_adt_elem e = { };
116 	struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
117 	u32 ip;
118 
119 	ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
120 	if (ip < map->first_ip || ip > map->last_ip)
121 		return -IPSET_ERR_BITMAP_RANGE;
122 
123 	e.id = ip_to_id(map, ip);
124 
125 	return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
126 }
127 
128 static int
129 bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
130 	       enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
131 {
132 	struct bitmap_ip *map = set->data;
133 	ipset_adtfn adtfn = set->variant->adt[adt];
134 	u32 ip = 0, ip_to = 0;
135 	struct bitmap_ip_adt_elem e = { };
136 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
137 	int ret = 0;
138 
139 	if (unlikely(!tb[IPSET_ATTR_IP] ||
140 		     !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
141 		     !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
142 		     !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
143 		return -IPSET_ERR_PROTOCOL;
144 
145 	if (tb[IPSET_ATTR_LINENO])
146 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
147 
148 	ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
149 	      ip_set_get_extensions(set, tb, &ext);
150 	if (ret)
151 		return ret;
152 
153 	if (ip < map->first_ip || ip > map->last_ip)
154 		return -IPSET_ERR_BITMAP_RANGE;
155 
156 	if (adt == IPSET_TEST) {
157 		e.id = ip_to_id(map, ip);
158 		return adtfn(set, &e, &ext, &ext, flags);
159 	}
160 
161 	if (tb[IPSET_ATTR_IP_TO]) {
162 		ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
163 		if (ret)
164 			return ret;
165 		if (ip > ip_to) {
166 			swap(ip, ip_to);
167 			if (ip < map->first_ip)
168 				return -IPSET_ERR_BITMAP_RANGE;
169 		}
170 	} else if (tb[IPSET_ATTR_CIDR]) {
171 		u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
172 
173 		if (!cidr || cidr > 32)
174 			return -IPSET_ERR_INVALID_CIDR;
175 		ip_set_mask_from_to(ip, ip_to, cidr);
176 	} else
177 		ip_to = ip;
178 
179 	if (ip_to > map->last_ip)
180 		return -IPSET_ERR_BITMAP_RANGE;
181 
182 	for (; !before(ip_to, ip); ip += map->hosts) {
183 		e.id = ip_to_id(map, ip);
184 		ret = adtfn(set, &e, &ext, &ext, flags);
185 
186 		if (ret && !ip_set_eexist(ret, flags))
187 			return ret;
188 		else
189 			ret = 0;
190 	}
191 	return ret;
192 }
193 
194 static bool
195 bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
196 {
197 	const struct bitmap_ip *x = a->data;
198 	const struct bitmap_ip *y = b->data;
199 
200 	return x->first_ip == y->first_ip &&
201 	       x->last_ip == y->last_ip &&
202 	       x->netmask == y->netmask &&
203 	       a->timeout == b->timeout &&
204 	       a->extensions == b->extensions;
205 }
206 
207 /* Plain variant */
208 
209 struct bitmap_ip_elem {
210 };
211 
212 #include "ip_set_bitmap_gen.h"
213 
214 /* Create bitmap:ip type of sets */
215 
216 static bool
217 init_map_ip(struct ip_set *set, struct bitmap_ip *map,
218 	    u32 first_ip, u32 last_ip,
219 	    u32 elements, u32 hosts, u8 netmask)
220 {
221 	map->members = ip_set_alloc(map->memsize);
222 	if (!map->members)
223 		return false;
224 	if (set->dsize) {
225 		map->extensions = ip_set_alloc(set->dsize * elements);
226 		if (!map->extensions) {
227 			kfree(map->members);
228 			return false;
229 		}
230 	}
231 	map->first_ip = first_ip;
232 	map->last_ip = last_ip;
233 	map->elements = elements;
234 	map->hosts = hosts;
235 	map->netmask = netmask;
236 	set->timeout = IPSET_NO_TIMEOUT;
237 
238 	set->data = map;
239 	set->family = NFPROTO_IPV4;
240 
241 	return true;
242 }
243 
244 static int
245 bitmap_ip_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
246 		 u32 flags)
247 {
248 	struct bitmap_ip *map;
249 	u32 first_ip = 0, last_ip = 0, hosts;
250 	u64 elements;
251 	u8 netmask = 32;
252 	int ret;
253 
254 	if (unlikely(!tb[IPSET_ATTR_IP] ||
255 		     !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
256 		     !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
257 		return -IPSET_ERR_PROTOCOL;
258 
259 	ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
260 	if (ret)
261 		return ret;
262 
263 	if (tb[IPSET_ATTR_IP_TO]) {
264 		ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip);
265 		if (ret)
266 			return ret;
267 		if (first_ip > last_ip) {
268 			u32 tmp = first_ip;
269 
270 			first_ip = last_ip;
271 			last_ip = tmp;
272 		}
273 	} else if (tb[IPSET_ATTR_CIDR]) {
274 		u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
275 
276 		if (cidr >= 32)
277 			return -IPSET_ERR_INVALID_CIDR;
278 		ip_set_mask_from_to(first_ip, last_ip, cidr);
279 	} else
280 		return -IPSET_ERR_PROTOCOL;
281 
282 	if (tb[IPSET_ATTR_NETMASK]) {
283 		netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]);
284 
285 		if (netmask > 32)
286 			return -IPSET_ERR_INVALID_NETMASK;
287 
288 		first_ip &= ip_set_hostmask(netmask);
289 		last_ip |= ~ip_set_hostmask(netmask);
290 	}
291 
292 	if (netmask == 32) {
293 		hosts = 1;
294 		elements = (u64)last_ip - first_ip + 1;
295 	} else {
296 		u8 mask_bits;
297 		u32 mask;
298 
299 		mask = range_to_mask(first_ip, last_ip, &mask_bits);
300 
301 		if ((!mask && (first_ip || last_ip != 0xFFFFFFFF)) ||
302 		    netmask <= mask_bits)
303 			return -IPSET_ERR_BITMAP_RANGE;
304 
305 		pr_debug("mask_bits %u, netmask %u\n", mask_bits, netmask);
306 		hosts = 2 << (32 - netmask - 1);
307 		elements = 2 << (netmask - mask_bits - 1);
308 	}
309 	if (elements > IPSET_BITMAP_MAX_RANGE + 1)
310 		return -IPSET_ERR_BITMAP_RANGE_SIZE;
311 
312 	pr_debug("hosts %u, elements %llu\n",
313 		 hosts, (unsigned long long)elements);
314 
315 	map = kzalloc(sizeof(*map), GFP_KERNEL);
316 	if (!map)
317 		return -ENOMEM;
318 
319 	map->memsize = bitmap_bytes(0, elements - 1);
320 	set->variant = &bitmap_ip;
321 	set->dsize = ip_set_elem_len(set, tb, 0);
322 	if (!init_map_ip(set, map, first_ip, last_ip,
323 			 elements, hosts, netmask)) {
324 		kfree(map);
325 		return -ENOMEM;
326 	}
327 	if (tb[IPSET_ATTR_TIMEOUT]) {
328 		set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
329 		bitmap_ip_gc_init(set, bitmap_ip_gc);
330 	}
331 	return 0;
332 }
333 
334 static struct ip_set_type bitmap_ip_type __read_mostly = {
335 	.name		= "bitmap:ip",
336 	.protocol	= IPSET_PROTOCOL,
337 	.features	= IPSET_TYPE_IP,
338 	.dimension	= IPSET_DIM_ONE,
339 	.family		= NFPROTO_IPV4,
340 	.revision_min	= IPSET_TYPE_REV_MIN,
341 	.revision_max	= IPSET_TYPE_REV_MAX,
342 	.create		= bitmap_ip_create,
343 	.create_policy	= {
344 		[IPSET_ATTR_IP]		= { .type = NLA_NESTED },
345 		[IPSET_ATTR_IP_TO]	= { .type = NLA_NESTED },
346 		[IPSET_ATTR_CIDR]	= { .type = NLA_U8 },
347 		[IPSET_ATTR_NETMASK]	= { .type = NLA_U8  },
348 		[IPSET_ATTR_TIMEOUT]	= { .type = NLA_U32 },
349 		[IPSET_ATTR_CADT_FLAGS]	= { .type = NLA_U32 },
350 	},
351 	.adt_policy	= {
352 		[IPSET_ATTR_IP]		= { .type = NLA_NESTED },
353 		[IPSET_ATTR_IP_TO]	= { .type = NLA_NESTED },
354 		[IPSET_ATTR_CIDR]	= { .type = NLA_U8 },
355 		[IPSET_ATTR_TIMEOUT]	= { .type = NLA_U32 },
356 		[IPSET_ATTR_LINENO]	= { .type = NLA_U32 },
357 		[IPSET_ATTR_BYTES]	= { .type = NLA_U64 },
358 		[IPSET_ATTR_PACKETS]	= { .type = NLA_U64 },
359 		[IPSET_ATTR_COMMENT]	= { .type = NLA_NUL_STRING },
360 	},
361 	.me		= THIS_MODULE,
362 };
363 
364 static int __init
365 bitmap_ip_init(void)
366 {
367 	return ip_set_type_register(&bitmap_ip_type);
368 }
369 
370 static void __exit
371 bitmap_ip_fini(void)
372 {
373 	ip_set_type_unregister(&bitmap_ip_type);
374 }
375 
376 module_init(bitmap_ip_init);
377 module_exit(bitmap_ip_fini);
378