1 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2  *                         Patrick Schaaf <bof@bof.de>
3  *			   Martin Josefsson <gandalf@wlug.westbo.se>
4  * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10 
11 /* Kernel module implementing an IP set type: the bitmap:ip,mac type */
12 
13 #include <linux/module.h>
14 #include <linux/ip.h>
15 #include <linux/etherdevice.h>
16 #include <linux/skbuff.h>
17 #include <linux/errno.h>
18 #include <linux/if_ether.h>
19 #include <linux/netlink.h>
20 #include <linux/jiffies.h>
21 #include <linux/timer.h>
22 #include <net/netlink.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 /*				2	   Comment support added */
31 #define IPSET_TYPE_REV_MAX	3	/* skbinfo support added */
32 
33 MODULE_LICENSE("GPL");
34 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
35 IP_SET_MODULE_DESC("bitmap:ip,mac", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
36 MODULE_ALIAS("ip_set_bitmap:ip,mac");
37 
38 #define MTYPE		bitmap_ipmac
39 #define HOST_MASK	32
40 #define IP_SET_BITMAP_STORED_TIMEOUT
41 
42 enum {
43 	MAC_UNSET,		/* element is set, without MAC */
44 	MAC_FILLED,		/* element is set with MAC */
45 };
46 
47 /* Type structure */
48 struct bitmap_ipmac {
49 	void *members;		/* the set members */
50 	u32 first_ip;		/* host byte order, included in range */
51 	u32 last_ip;		/* host byte order, included in range */
52 	u32 elements;		/* number of max elements in the set */
53 	size_t memsize;		/* members size */
54 	struct timer_list gc;	/* garbage collector */
55 	unsigned char extensions[0]	/* MAC + data extensions */
56 		__aligned(__alignof__(u64));
57 };
58 
59 /* ADT structure for generic function args */
60 struct bitmap_ipmac_adt_elem {
61 	unsigned char ether[ETH_ALEN] __aligned(2);
62 	u16 id;
63 	u16 add_mac;
64 };
65 
66 struct bitmap_ipmac_elem {
67 	unsigned char ether[ETH_ALEN];
68 	unsigned char filled;
69 } __aligned(__alignof__(u64));
70 
71 static inline u32
72 ip_to_id(const struct bitmap_ipmac *m, u32 ip)
73 {
74 	return ip - m->first_ip;
75 }
76 
77 #define get_elem(extensions, id, dsize)		\
78 	(struct bitmap_ipmac_elem *)(extensions + (id) * (dsize))
79 
80 #define get_const_elem(extensions, id, dsize)	\
81 	(const struct bitmap_ipmac_elem *)(extensions + (id) * (dsize))
82 
83 /* Common functions */
84 
85 static inline int
86 bitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e,
87 		     const struct bitmap_ipmac *map, size_t dsize)
88 {
89 	const struct bitmap_ipmac_elem *elem;
90 
91 	if (!test_bit(e->id, map->members))
92 		return 0;
93 	elem = get_const_elem(map->extensions, e->id, dsize);
94 	if (e->add_mac && elem->filled == MAC_FILLED)
95 		return ether_addr_equal(e->ether, elem->ether);
96 	/* Trigger kernel to fill out the ethernet address */
97 	return -EAGAIN;
98 }
99 
100 static inline int
101 bitmap_ipmac_gc_test(u16 id, const struct bitmap_ipmac *map, size_t dsize)
102 {
103 	const struct bitmap_ipmac_elem *elem;
104 
105 	if (!test_bit(id, map->members))
106 		return 0;
107 	elem = get_const_elem(map->extensions, id, dsize);
108 	/* Timer not started for the incomplete elements */
109 	return elem->filled == MAC_FILLED;
110 }
111 
112 static inline int
113 bitmap_ipmac_is_filled(const struct bitmap_ipmac_elem *elem)
114 {
115 	return elem->filled == MAC_FILLED;
116 }
117 
118 static inline int
119 bitmap_ipmac_add_timeout(unsigned long *timeout,
120 			 const struct bitmap_ipmac_adt_elem *e,
121 			 const struct ip_set_ext *ext, struct ip_set *set,
122 			 struct bitmap_ipmac *map, int mode)
123 {
124 	u32 t = ext->timeout;
125 
126 	if (mode == IPSET_ADD_START_STORED_TIMEOUT) {
127 		if (t == set->timeout)
128 			/* Timeout was not specified, get stored one */
129 			t = *timeout;
130 		ip_set_timeout_set(timeout, t);
131 	} else {
132 		/* If MAC is unset yet, we store plain timeout value
133 		 * because the timer is not activated yet
134 		 * and we can reuse it later when MAC is filled out,
135 		 * possibly by the kernel
136 		 */
137 		if (e->add_mac)
138 			ip_set_timeout_set(timeout, t);
139 		else
140 			*timeout = t;
141 	}
142 	return 0;
143 }
144 
145 static inline int
146 bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e,
147 		    struct bitmap_ipmac *map, u32 flags, size_t dsize)
148 {
149 	struct bitmap_ipmac_elem *elem;
150 
151 	elem = get_elem(map->extensions, e->id, dsize);
152 	if (test_bit(e->id, map->members)) {
153 		if (elem->filled == MAC_FILLED) {
154 			if (e->add_mac &&
155 			    (flags & IPSET_FLAG_EXIST) &&
156 			    !ether_addr_equal(e->ether, elem->ether)) {
157 				/* memcpy isn't atomic */
158 				clear_bit(e->id, map->members);
159 				smp_mb__after_atomic();
160 				ether_addr_copy(elem->ether, e->ether);
161 			}
162 			return IPSET_ADD_FAILED;
163 		} else if (!e->add_mac)
164 			/* Already added without ethernet address */
165 			return IPSET_ADD_FAILED;
166 		/* Fill the MAC address and trigger the timer activation */
167 		clear_bit(e->id, map->members);
168 		smp_mb__after_atomic();
169 		ether_addr_copy(elem->ether, e->ether);
170 		elem->filled = MAC_FILLED;
171 		return IPSET_ADD_START_STORED_TIMEOUT;
172 	} else if (e->add_mac) {
173 		/* We can store MAC too */
174 		ether_addr_copy(elem->ether, e->ether);
175 		elem->filled = MAC_FILLED;
176 		return 0;
177 	}
178 	elem->filled = MAC_UNSET;
179 	/* MAC is not stored yet, don't start timer */
180 	return IPSET_ADD_STORE_PLAIN_TIMEOUT;
181 }
182 
183 static inline int
184 bitmap_ipmac_do_del(const struct bitmap_ipmac_adt_elem *e,
185 		    struct bitmap_ipmac *map)
186 {
187 	return !test_and_clear_bit(e->id, map->members);
188 }
189 
190 static inline int
191 bitmap_ipmac_do_list(struct sk_buff *skb, const struct bitmap_ipmac *map,
192 		     u32 id, size_t dsize)
193 {
194 	const struct bitmap_ipmac_elem *elem =
195 		get_const_elem(map->extensions, id, dsize);
196 
197 	return nla_put_ipaddr4(skb, IPSET_ATTR_IP,
198 			       htonl(map->first_ip + id)) ||
199 	       (elem->filled == MAC_FILLED &&
200 		nla_put(skb, IPSET_ATTR_ETHER, ETH_ALEN, elem->ether));
201 }
202 
203 static inline int
204 bitmap_ipmac_do_head(struct sk_buff *skb, const struct bitmap_ipmac *map)
205 {
206 	return nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip)) ||
207 	       nla_put_ipaddr4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip));
208 }
209 
210 static int
211 bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
212 		  const struct xt_action_param *par,
213 		  enum ipset_adt adt, struct ip_set_adt_opt *opt)
214 {
215 	struct bitmap_ipmac *map = set->data;
216 	ipset_adtfn adtfn = set->variant->adt[adt];
217 	struct bitmap_ipmac_adt_elem e = { .id = 0, .add_mac = 1 };
218 	struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
219 	u32 ip;
220 
221 	/* MAC can be src only */
222 	if (!(opt->flags & IPSET_DIM_TWO_SRC))
223 		return 0;
224 
225 	ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
226 	if (ip < map->first_ip || ip > map->last_ip)
227 		return -IPSET_ERR_BITMAP_RANGE;
228 
229 	/* Backward compatibility: we don't check the second flag */
230 	if (skb_mac_header(skb) < skb->head ||
231 	    (skb_mac_header(skb) + ETH_HLEN) > skb->data)
232 		return -EINVAL;
233 
234 	e.id = ip_to_id(map, ip);
235 	memcpy(e.ether, eth_hdr(skb)->h_source, ETH_ALEN);
236 
237 	return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
238 }
239 
240 static int
241 bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[],
242 		  enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
243 {
244 	const struct bitmap_ipmac *map = set->data;
245 	ipset_adtfn adtfn = set->variant->adt[adt];
246 	struct bitmap_ipmac_adt_elem e = { .id = 0 };
247 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
248 	u32 ip = 0;
249 	int ret = 0;
250 
251 	if (tb[IPSET_ATTR_LINENO])
252 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
253 
254 	if (unlikely(!tb[IPSET_ATTR_IP]))
255 		return -IPSET_ERR_PROTOCOL;
256 
257 	ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
258 	if (ret)
259 		return ret;
260 
261 	ret = ip_set_get_extensions(set, tb, &ext);
262 	if (ret)
263 		return ret;
264 
265 	if (ip < map->first_ip || ip > map->last_ip)
266 		return -IPSET_ERR_BITMAP_RANGE;
267 
268 	e.id = ip_to_id(map, ip);
269 	if (tb[IPSET_ATTR_ETHER]) {
270 		if (nla_len(tb[IPSET_ATTR_ETHER]) != ETH_ALEN)
271 			return -IPSET_ERR_PROTOCOL;
272 		memcpy(e.ether, nla_data(tb[IPSET_ATTR_ETHER]), ETH_ALEN);
273 		e.add_mac = 1;
274 	}
275 	ret = adtfn(set, &e, &ext, &ext, flags);
276 
277 	return ip_set_eexist(ret, flags) ? 0 : ret;
278 }
279 
280 static bool
281 bitmap_ipmac_same_set(const struct ip_set *a, const struct ip_set *b)
282 {
283 	const struct bitmap_ipmac *x = a->data;
284 	const struct bitmap_ipmac *y = b->data;
285 
286 	return x->first_ip == y->first_ip &&
287 	       x->last_ip == y->last_ip &&
288 	       a->timeout == b->timeout &&
289 	       a->extensions == b->extensions;
290 }
291 
292 /* Plain variant */
293 
294 #include "ip_set_bitmap_gen.h"
295 
296 /* Create bitmap:ip,mac type of sets */
297 
298 static bool
299 init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
300 	       u32 first_ip, u32 last_ip, u32 elements)
301 {
302 	map->members = ip_set_alloc(map->memsize);
303 	if (!map->members)
304 		return false;
305 	map->first_ip = first_ip;
306 	map->last_ip = last_ip;
307 	map->elements = elements;
308 	set->timeout = IPSET_NO_TIMEOUT;
309 
310 	set->data = map;
311 	set->family = NFPROTO_IPV4;
312 
313 	return true;
314 }
315 
316 static int
317 bitmap_ipmac_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
318 		    u32 flags)
319 {
320 	u32 first_ip = 0, last_ip = 0;
321 	u64 elements;
322 	struct bitmap_ipmac *map;
323 	int ret;
324 
325 	if (unlikely(!tb[IPSET_ATTR_IP] ||
326 		     !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
327 		     !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
328 		return -IPSET_ERR_PROTOCOL;
329 
330 	ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
331 	if (ret)
332 		return ret;
333 
334 	if (tb[IPSET_ATTR_IP_TO]) {
335 		ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip);
336 		if (ret)
337 			return ret;
338 		if (first_ip > last_ip) {
339 			u32 tmp = first_ip;
340 
341 			first_ip = last_ip;
342 			last_ip = tmp;
343 		}
344 	} else if (tb[IPSET_ATTR_CIDR]) {
345 		u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
346 
347 		if (cidr >= HOST_MASK)
348 			return -IPSET_ERR_INVALID_CIDR;
349 		ip_set_mask_from_to(first_ip, last_ip, cidr);
350 	} else {
351 		return -IPSET_ERR_PROTOCOL;
352 	}
353 
354 	elements = (u64)last_ip - first_ip + 1;
355 
356 	if (elements > IPSET_BITMAP_MAX_RANGE + 1)
357 		return -IPSET_ERR_BITMAP_RANGE_SIZE;
358 
359 	set->dsize = ip_set_elem_len(set, tb,
360 				     sizeof(struct bitmap_ipmac_elem),
361 				     __alignof__(struct bitmap_ipmac_elem));
362 	map = ip_set_alloc(sizeof(*map) + elements * set->dsize);
363 	if (!map)
364 		return -ENOMEM;
365 
366 	map->memsize = bitmap_bytes(0, elements - 1);
367 	set->variant = &bitmap_ipmac;
368 	if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
369 		kfree(map);
370 		return -ENOMEM;
371 	}
372 	if (tb[IPSET_ATTR_TIMEOUT]) {
373 		set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
374 		bitmap_ipmac_gc_init(set, bitmap_ipmac_gc);
375 	}
376 	return 0;
377 }
378 
379 static struct ip_set_type bitmap_ipmac_type = {
380 	.name		= "bitmap:ip,mac",
381 	.protocol	= IPSET_PROTOCOL,
382 	.features	= IPSET_TYPE_IP | IPSET_TYPE_MAC,
383 	.dimension	= IPSET_DIM_TWO,
384 	.family		= NFPROTO_IPV4,
385 	.revision_min	= IPSET_TYPE_REV_MIN,
386 	.revision_max	= IPSET_TYPE_REV_MAX,
387 	.create		= bitmap_ipmac_create,
388 	.create_policy	= {
389 		[IPSET_ATTR_IP]		= { .type = NLA_NESTED },
390 		[IPSET_ATTR_IP_TO]	= { .type = NLA_NESTED },
391 		[IPSET_ATTR_CIDR]	= { .type = NLA_U8 },
392 		[IPSET_ATTR_TIMEOUT]	= { .type = NLA_U32 },
393 		[IPSET_ATTR_CADT_FLAGS]	= { .type = NLA_U32 },
394 	},
395 	.adt_policy	= {
396 		[IPSET_ATTR_IP]		= { .type = NLA_NESTED },
397 		[IPSET_ATTR_ETHER]	= { .type = NLA_BINARY,
398 					    .len  = ETH_ALEN },
399 		[IPSET_ATTR_TIMEOUT]	= { .type = NLA_U32 },
400 		[IPSET_ATTR_LINENO]	= { .type = NLA_U32 },
401 		[IPSET_ATTR_BYTES]	= { .type = NLA_U64 },
402 		[IPSET_ATTR_PACKETS]	= { .type = NLA_U64 },
403 		[IPSET_ATTR_COMMENT]	= { .type = NLA_NUL_STRING,
404 					    .len  = IPSET_MAX_COMMENT_SIZE },
405 		[IPSET_ATTR_SKBMARK]	= { .type = NLA_U64 },
406 		[IPSET_ATTR_SKBPRIO]	= { .type = NLA_U32 },
407 		[IPSET_ATTR_SKBQUEUE]	= { .type = NLA_U16 },
408 	},
409 	.me		= THIS_MODULE,
410 };
411 
412 static int __init
413 bitmap_ipmac_init(void)
414 {
415 	return ip_set_type_register(&bitmap_ipmac_type);
416 }
417 
418 static void __exit
419 bitmap_ipmac_fini(void)
420 {
421 	rcu_barrier();
422 	ip_set_type_unregister(&bitmap_ipmac_type);
423 }
424 
425 module_init(bitmap_ipmac_init);
426 module_exit(bitmap_ipmac_fini);
427