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-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
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.
11 /* Kernel module implementing an IP set type: the bitmap:ip,mac type */
13 #include <linux/module.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>
24 #include <linux/netfilter/ipset/pfxlen.h>
25 #include <linux/netfilter/ipset/ip_set.h>
26 #include <linux/netfilter/ipset/ip_set_timeout.h>
27 #include <linux/netfilter/ipset/ip_set_bitmap.h>
29 #define REVISION_MIN 0
30 #define REVISION_MAX 0
32 MODULE_LICENSE("GPL");
33 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
34 IP_SET_MODULE_DESC("bitmap:ip,mac", REVISION_MIN
, REVISION_MAX
);
35 MODULE_ALIAS("ip_set_bitmap:ip,mac");
38 MAC_EMPTY
, /* element is not set */
39 MAC_FILLED
, /* element is set with MAC */
40 MAC_UNSET
, /* element is set, without MAC */
45 void *members
; /* the set members */
46 u32 first_ip
; /* host byte order, included in range */
47 u32 last_ip
; /* host byte order, included in range */
48 u32 timeout
; /* timeout value */
49 struct timer_list gc
; /* garbage collector */
50 size_t dsize
; /* size of element */
53 /* ADT structure for generic function args */
55 u32 id
; /* id in array */
56 unsigned char *ether
; /* ethernet address */
59 /* Member element without and with timeout */
62 unsigned char ether
[ETH_ALEN
];
64 } __attribute__ ((aligned
));
67 unsigned char ether
[ETH_ALEN
];
69 unsigned long timeout
;
70 } __attribute__ ((aligned
));
73 bitmap_ipmac_elem(const struct bitmap_ipmac
*map
, u32 id
)
75 return (void *)((char *)map
->members
+ id
* map
->dsize
);
79 bitmap_timeout(const struct bitmap_ipmac
*map
, u32 id
)
81 const struct ipmac_telem
*elem
= bitmap_ipmac_elem(map
, id
);
83 return ip_set_timeout_test(elem
->timeout
);
87 bitmap_expired(const struct bitmap_ipmac
*map
, u32 id
)
89 const struct ipmac_telem
*elem
= bitmap_ipmac_elem(map
, id
);
91 return ip_set_timeout_expired(elem
->timeout
);
95 bitmap_ipmac_exist(const struct ipmac_telem
*elem
)
97 return elem
->match
== MAC_UNSET
||
98 (elem
->match
== MAC_FILLED
&&
99 !ip_set_timeout_expired(elem
->timeout
));
105 bitmap_ipmac_test(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
107 const struct bitmap_ipmac
*map
= set
->data
;
108 const struct ipmac
*data
= value
;
109 const struct ipmac_elem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
111 switch (elem
->match
) {
113 /* Trigger kernel to fill out the ethernet address */
116 return data
->ether
== NULL
||
117 ether_addr_equal(data
->ether
, elem
->ether
);
123 bitmap_ipmac_add(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
125 struct bitmap_ipmac
*map
= set
->data
;
126 const struct ipmac
*data
= value
;
127 struct ipmac_elem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
129 switch (elem
->match
) {
132 /* Already added without ethernet address */
133 return -IPSET_ERR_EXIST
;
134 /* Fill the MAC address */
135 memcpy(elem
->ether
, data
->ether
, ETH_ALEN
);
136 elem
->match
= MAC_FILLED
;
139 return -IPSET_ERR_EXIST
;
142 memcpy(elem
->ether
, data
->ether
, ETH_ALEN
);
143 elem
->match
= MAC_FILLED
;
145 elem
->match
= MAC_UNSET
;
152 bitmap_ipmac_del(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
154 struct bitmap_ipmac
*map
= set
->data
;
155 const struct ipmac
*data
= value
;
156 struct ipmac_elem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
158 if (elem
->match
== MAC_EMPTY
)
159 return -IPSET_ERR_EXIST
;
161 elem
->match
= MAC_EMPTY
;
167 bitmap_ipmac_list(const struct ip_set
*set
,
168 struct sk_buff
*skb
, struct netlink_callback
*cb
)
170 const struct bitmap_ipmac
*map
= set
->data
;
171 const struct ipmac_elem
*elem
;
172 struct nlattr
*atd
, *nested
;
173 u32 id
, first
= cb
->args
[2];
174 u32 last
= map
->last_ip
- map
->first_ip
;
176 atd
= ipset_nest_start(skb
, IPSET_ATTR_ADT
);
179 for (; cb
->args
[2] <= last
; cb
->args
[2]++) {
181 elem
= bitmap_ipmac_elem(map
, id
);
182 if (elem
->match
== MAC_EMPTY
)
184 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
187 nla_nest_cancel(skb
, atd
);
190 goto nla_put_failure
;
192 if (nla_put_ipaddr4(skb
, IPSET_ATTR_IP
,
193 htonl(map
->first_ip
+ id
)) ||
194 (elem
->match
== MAC_FILLED
&&
195 nla_put(skb
, IPSET_ATTR_ETHER
, ETH_ALEN
,
197 goto nla_put_failure
;
198 ipset_nest_end(skb
, nested
);
200 ipset_nest_end(skb
, atd
);
201 /* Set listing finished */
207 nla_nest_cancel(skb
, nested
);
208 ipset_nest_end(skb
, atd
);
209 if (unlikely(id
== first
)) {
216 /* Timeout variant */
219 bitmap_ipmac_ttest(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
221 const struct bitmap_ipmac
*map
= set
->data
;
222 const struct ipmac
*data
= value
;
223 const struct ipmac_elem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
225 switch (elem
->match
) {
227 /* Trigger kernel to fill out the ethernet address */
230 return (data
->ether
== NULL
||
231 ether_addr_equal(data
->ether
, elem
->ether
)) &&
232 !bitmap_expired(map
, data
->id
);
238 bitmap_ipmac_tadd(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
240 struct bitmap_ipmac
*map
= set
->data
;
241 const struct ipmac
*data
= value
;
242 struct ipmac_telem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
243 bool flag_exist
= flags
& IPSET_FLAG_EXIST
;
245 switch (elem
->match
) {
247 if (!(data
->ether
|| flag_exist
))
248 /* Already added without ethernet address */
249 return -IPSET_ERR_EXIST
;
250 /* Fill the MAC address and activate the timer */
251 memcpy(elem
->ether
, data
->ether
, ETH_ALEN
);
252 elem
->match
= MAC_FILLED
;
253 if (timeout
== map
->timeout
)
254 /* Timeout was not specified, get stored one */
255 timeout
= elem
->timeout
;
256 elem
->timeout
= ip_set_timeout_set(timeout
);
259 if (!(bitmap_expired(map
, data
->id
) || flag_exist
))
260 return -IPSET_ERR_EXIST
;
264 memcpy(elem
->ether
, data
->ether
, ETH_ALEN
);
265 elem
->match
= MAC_FILLED
;
267 elem
->match
= MAC_UNSET
;
268 /* If MAC is unset yet, we store plain timeout value
269 * because the timer is not activated yet
270 * and we can reuse it later when MAC is filled out,
271 * possibly by the kernel */
272 elem
->timeout
= data
->ether
? ip_set_timeout_set(timeout
)
281 bitmap_ipmac_tdel(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
283 struct bitmap_ipmac
*map
= set
->data
;
284 const struct ipmac
*data
= value
;
285 struct ipmac_telem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
287 if (elem
->match
== MAC_EMPTY
|| bitmap_expired(map
, data
->id
))
288 return -IPSET_ERR_EXIST
;
290 elem
->match
= MAC_EMPTY
;
296 bitmap_ipmac_tlist(const struct ip_set
*set
,
297 struct sk_buff
*skb
, struct netlink_callback
*cb
)
299 const struct bitmap_ipmac
*map
= set
->data
;
300 const struct ipmac_telem
*elem
;
301 struct nlattr
*atd
, *nested
;
302 u32 id
, first
= cb
->args
[2];
303 u32 timeout
, last
= map
->last_ip
- map
->first_ip
;
305 atd
= ipset_nest_start(skb
, IPSET_ATTR_ADT
);
308 for (; cb
->args
[2] <= last
; cb
->args
[2]++) {
310 elem
= bitmap_ipmac_elem(map
, id
);
311 if (!bitmap_ipmac_exist(elem
))
313 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
316 nla_nest_cancel(skb
, atd
);
319 goto nla_put_failure
;
321 if (nla_put_ipaddr4(skb
, IPSET_ATTR_IP
,
322 htonl(map
->first_ip
+ id
)) ||
323 (elem
->match
== MAC_FILLED
&&
324 nla_put(skb
, IPSET_ATTR_ETHER
, ETH_ALEN
,
326 goto nla_put_failure
;
327 timeout
= elem
->match
== MAC_UNSET
? elem
->timeout
328 : ip_set_timeout_get(elem
->timeout
);
329 if (nla_put_net32(skb
, IPSET_ATTR_TIMEOUT
, htonl(timeout
)))
330 goto nla_put_failure
;
331 ipset_nest_end(skb
, nested
);
333 ipset_nest_end(skb
, atd
);
334 /* Set listing finished */
340 nla_nest_cancel(skb
, nested
);
341 ipset_nest_end(skb
, atd
);
342 if (unlikely(id
== first
)) {
350 bitmap_ipmac_kadt(struct ip_set
*set
, const struct sk_buff
*skb
,
351 const struct xt_action_param
*par
,
352 enum ipset_adt adt
, const struct ip_set_adt_opt
*opt
)
354 struct bitmap_ipmac
*map
= set
->data
;
355 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
358 /* MAC can be src only */
359 if (!(opt
->flags
& IPSET_DIM_TWO_SRC
))
362 data
.id
= ntohl(ip4addr(skb
, opt
->flags
& IPSET_DIM_ONE_SRC
));
363 if (data
.id
< map
->first_ip
|| data
.id
> map
->last_ip
)
364 return -IPSET_ERR_BITMAP_RANGE
;
366 /* Backward compatibility: we don't check the second flag */
367 if (skb_mac_header(skb
) < skb
->head
||
368 (skb_mac_header(skb
) + ETH_HLEN
) > skb
->data
)
371 data
.id
-= map
->first_ip
;
372 data
.ether
= eth_hdr(skb
)->h_source
;
374 return adtfn(set
, &data
, opt_timeout(opt
, map
), opt
->cmdflags
);
378 bitmap_ipmac_uadt(struct ip_set
*set
, struct nlattr
*tb
[],
379 enum ipset_adt adt
, u32
*lineno
, u32 flags
, bool retried
)
381 const struct bitmap_ipmac
*map
= set
->data
;
382 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
384 u32 timeout
= map
->timeout
;
387 if (unlikely(!tb
[IPSET_ATTR_IP
] ||
388 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
)))
389 return -IPSET_ERR_PROTOCOL
;
391 if (tb
[IPSET_ATTR_LINENO
])
392 *lineno
= nla_get_u32(tb
[IPSET_ATTR_LINENO
]);
394 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &data
.id
);
398 if (data
.id
< map
->first_ip
|| data
.id
> map
->last_ip
)
399 return -IPSET_ERR_BITMAP_RANGE
;
401 if (tb
[IPSET_ATTR_ETHER
])
402 data
.ether
= nla_data(tb
[IPSET_ATTR_ETHER
]);
406 if (tb
[IPSET_ATTR_TIMEOUT
]) {
407 if (!with_timeout(map
->timeout
))
408 return -IPSET_ERR_TIMEOUT
;
409 timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
412 data
.id
-= map
->first_ip
;
414 ret
= adtfn(set
, &data
, timeout
, flags
);
416 return ip_set_eexist(ret
, flags
) ? 0 : ret
;
420 bitmap_ipmac_destroy(struct ip_set
*set
)
422 struct bitmap_ipmac
*map
= set
->data
;
424 if (with_timeout(map
->timeout
))
425 del_timer_sync(&map
->gc
);
427 ip_set_free(map
->members
);
434 bitmap_ipmac_flush(struct ip_set
*set
)
436 struct bitmap_ipmac
*map
= set
->data
;
438 memset(map
->members
, 0,
439 (map
->last_ip
- map
->first_ip
+ 1) * map
->dsize
);
443 bitmap_ipmac_head(struct ip_set
*set
, struct sk_buff
*skb
)
445 const struct bitmap_ipmac
*map
= set
->data
;
446 struct nlattr
*nested
;
448 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
450 goto nla_put_failure
;
451 if (nla_put_ipaddr4(skb
, IPSET_ATTR_IP
, htonl(map
->first_ip
)) ||
452 nla_put_ipaddr4(skb
, IPSET_ATTR_IP_TO
, htonl(map
->last_ip
)) ||
453 nla_put_net32(skb
, IPSET_ATTR_REFERENCES
, htonl(set
->ref
- 1)) ||
454 nla_put_net32(skb
, IPSET_ATTR_MEMSIZE
,
456 ((map
->last_ip
- map
->first_ip
+ 1) *
458 (with_timeout(map
->timeout
) &&
459 nla_put_net32(skb
, IPSET_ATTR_TIMEOUT
, htonl(map
->timeout
))))
460 goto nla_put_failure
;
461 ipset_nest_end(skb
, nested
);
469 bitmap_ipmac_same_set(const struct ip_set
*a
, const struct ip_set
*b
)
471 const struct bitmap_ipmac
*x
= a
->data
;
472 const struct bitmap_ipmac
*y
= b
->data
;
474 return x
->first_ip
== y
->first_ip
&&
475 x
->last_ip
== y
->last_ip
&&
476 x
->timeout
== y
->timeout
;
479 static const struct ip_set_type_variant bitmap_ipmac
= {
480 .kadt
= bitmap_ipmac_kadt
,
481 .uadt
= bitmap_ipmac_uadt
,
483 [IPSET_ADD
] = bitmap_ipmac_add
,
484 [IPSET_DEL
] = bitmap_ipmac_del
,
485 [IPSET_TEST
] = bitmap_ipmac_test
,
487 .destroy
= bitmap_ipmac_destroy
,
488 .flush
= bitmap_ipmac_flush
,
489 .head
= bitmap_ipmac_head
,
490 .list
= bitmap_ipmac_list
,
491 .same_set
= bitmap_ipmac_same_set
,
494 static const struct ip_set_type_variant bitmap_tipmac
= {
495 .kadt
= bitmap_ipmac_kadt
,
496 .uadt
= bitmap_ipmac_uadt
,
498 [IPSET_ADD
] = bitmap_ipmac_tadd
,
499 [IPSET_DEL
] = bitmap_ipmac_tdel
,
500 [IPSET_TEST
] = bitmap_ipmac_ttest
,
502 .destroy
= bitmap_ipmac_destroy
,
503 .flush
= bitmap_ipmac_flush
,
504 .head
= bitmap_ipmac_head
,
505 .list
= bitmap_ipmac_tlist
,
506 .same_set
= bitmap_ipmac_same_set
,
510 bitmap_ipmac_gc(unsigned long ul_set
)
512 struct ip_set
*set
= (struct ip_set
*) ul_set
;
513 struct bitmap_ipmac
*map
= set
->data
;
514 struct ipmac_telem
*elem
;
515 u32 id
, last
= map
->last_ip
- map
->first_ip
;
517 /* We run parallel with other readers (test element)
518 * but adding/deleting new entries is locked out */
519 read_lock_bh(&set
->lock
);
520 for (id
= 0; id
<= last
; id
++) {
521 elem
= bitmap_ipmac_elem(map
, id
);
522 if (elem
->match
== MAC_FILLED
&&
523 ip_set_timeout_expired(elem
->timeout
))
524 elem
->match
= MAC_EMPTY
;
526 read_unlock_bh(&set
->lock
);
528 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
533 bitmap_ipmac_gc_init(struct ip_set
*set
)
535 struct bitmap_ipmac
*map
= set
->data
;
537 init_timer(&map
->gc
);
538 map
->gc
.data
= (unsigned long) set
;
539 map
->gc
.function
= bitmap_ipmac_gc
;
540 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
544 /* Create bitmap:ip,mac type of sets */
547 init_map_ipmac(struct ip_set
*set
, struct bitmap_ipmac
*map
,
548 u32 first_ip
, u32 last_ip
)
550 map
->members
= ip_set_alloc((last_ip
- first_ip
+ 1) * map
->dsize
);
553 map
->first_ip
= first_ip
;
554 map
->last_ip
= last_ip
;
555 map
->timeout
= IPSET_NO_TIMEOUT
;
558 set
->family
= NFPROTO_IPV4
;
564 bitmap_ipmac_create(struct ip_set
*set
, struct nlattr
*tb
[],
567 u32 first_ip
, last_ip
;
569 struct bitmap_ipmac
*map
;
572 if (unlikely(!tb
[IPSET_ATTR_IP
] ||
573 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
)))
574 return -IPSET_ERR_PROTOCOL
;
576 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &first_ip
);
580 if (tb
[IPSET_ATTR_IP_TO
]) {
581 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP_TO
], &last_ip
);
584 if (first_ip
> last_ip
) {
590 } else if (tb
[IPSET_ATTR_CIDR
]) {
591 u8 cidr
= nla_get_u8(tb
[IPSET_ATTR_CIDR
]);
594 return -IPSET_ERR_INVALID_CIDR
;
595 ip_set_mask_from_to(first_ip
, last_ip
, cidr
);
597 return -IPSET_ERR_PROTOCOL
;
599 elements
= (u64
)last_ip
- first_ip
+ 1;
601 if (elements
> IPSET_BITMAP_MAX_RANGE
+ 1)
602 return -IPSET_ERR_BITMAP_RANGE_SIZE
;
604 map
= kzalloc(sizeof(*map
), GFP_KERNEL
);
608 if (tb
[IPSET_ATTR_TIMEOUT
]) {
609 map
->dsize
= sizeof(struct ipmac_telem
);
611 if (!init_map_ipmac(set
, map
, first_ip
, last_ip
)) {
616 map
->timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
618 set
->variant
= &bitmap_tipmac
;
620 bitmap_ipmac_gc_init(set
);
622 map
->dsize
= sizeof(struct ipmac_elem
);
624 if (!init_map_ipmac(set
, map
, first_ip
, last_ip
)) {
628 set
->variant
= &bitmap_ipmac
;
634 static struct ip_set_type bitmap_ipmac_type
= {
635 .name
= "bitmap:ip,mac",
636 .protocol
= IPSET_PROTOCOL
,
637 .features
= IPSET_TYPE_IP
| IPSET_TYPE_MAC
,
638 .dimension
= IPSET_DIM_TWO
,
639 .family
= NFPROTO_IPV4
,
640 .revision_min
= REVISION_MIN
,
641 .revision_max
= REVISION_MAX
,
642 .create
= bitmap_ipmac_create
,
644 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
645 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
646 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
647 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
650 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
651 [IPSET_ATTR_ETHER
] = { .type
= NLA_BINARY
,
653 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
654 [IPSET_ATTR_LINENO
] = { .type
= NLA_U32
},
660 bitmap_ipmac_init(void)
662 return ip_set_type_register(&bitmap_ipmac_type
);
666 bitmap_ipmac_fini(void)
668 ip_set_type_unregister(&bitmap_ipmac_type
);
671 module_init(bitmap_ipmac_init
);
672 module_exit(bitmap_ipmac_fini
);