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 MODULE_LICENSE("GPL");
30 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
31 MODULE_DESCRIPTION("bitmap:ip,mac type of IP sets");
32 MODULE_ALIAS("ip_set_bitmap:ip,mac");
35 MAC_EMPTY
, /* element is not set */
36 MAC_FILLED
, /* element is set with MAC */
37 MAC_UNSET
, /* element is set, without MAC */
42 void *members
; /* the set members */
43 u32 first_ip
; /* host byte order, included in range */
44 u32 last_ip
; /* host byte order, included in range */
45 u32 timeout
; /* timeout value */
46 struct timer_list gc
; /* garbage collector */
47 size_t dsize
; /* size of element */
50 /* ADT structure for generic function args */
52 u32 id
; /* id in array */
53 unsigned char *ether
; /* ethernet address */
56 /* Member element without and with timeout */
59 unsigned char ether
[ETH_ALEN
];
61 } __attribute__ ((aligned
));
64 unsigned char ether
[ETH_ALEN
];
66 unsigned long timeout
;
67 } __attribute__ ((aligned
));
70 bitmap_ipmac_elem(const struct bitmap_ipmac
*map
, u32 id
)
72 return (void *)((char *)map
->members
+ id
* map
->dsize
);
76 bitmap_timeout(const struct bitmap_ipmac
*map
, u32 id
)
78 const struct ipmac_telem
*elem
= bitmap_ipmac_elem(map
, id
);
80 return ip_set_timeout_test(elem
->timeout
);
84 bitmap_expired(const struct bitmap_ipmac
*map
, u32 id
)
86 const struct ipmac_telem
*elem
= bitmap_ipmac_elem(map
, id
);
88 return ip_set_timeout_expired(elem
->timeout
);
92 bitmap_ipmac_exist(const struct ipmac_telem
*elem
)
94 return elem
->match
== MAC_UNSET
||
95 (elem
->match
== MAC_FILLED
&&
96 !ip_set_timeout_expired(elem
->timeout
));
102 bitmap_ipmac_test(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
104 const struct bitmap_ipmac
*map
= set
->data
;
105 const struct ipmac
*data
= value
;
106 const struct ipmac_elem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
108 switch (elem
->match
) {
110 /* Trigger kernel to fill out the ethernet address */
113 return data
->ether
== NULL
||
114 compare_ether_addr(data
->ether
, elem
->ether
) == 0;
120 bitmap_ipmac_add(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
122 struct bitmap_ipmac
*map
= set
->data
;
123 const struct ipmac
*data
= value
;
124 struct ipmac_elem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
126 switch (elem
->match
) {
129 /* Already added without ethernet address */
130 return -IPSET_ERR_EXIST
;
131 /* Fill the MAC address */
132 memcpy(elem
->ether
, data
->ether
, ETH_ALEN
);
133 elem
->match
= MAC_FILLED
;
136 return -IPSET_ERR_EXIST
;
139 memcpy(elem
->ether
, data
->ether
, ETH_ALEN
);
140 elem
->match
= MAC_FILLED
;
142 elem
->match
= MAC_UNSET
;
149 bitmap_ipmac_del(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
151 struct bitmap_ipmac
*map
= set
->data
;
152 const struct ipmac
*data
= value
;
153 struct ipmac_elem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
155 if (elem
->match
== MAC_EMPTY
)
156 return -IPSET_ERR_EXIST
;
158 elem
->match
= MAC_EMPTY
;
164 bitmap_ipmac_list(const struct ip_set
*set
,
165 struct sk_buff
*skb
, struct netlink_callback
*cb
)
167 const struct bitmap_ipmac
*map
= set
->data
;
168 const struct ipmac_elem
*elem
;
169 struct nlattr
*atd
, *nested
;
170 u32 id
, first
= cb
->args
[2];
171 u32 last
= map
->last_ip
- map
->first_ip
;
173 atd
= ipset_nest_start(skb
, IPSET_ATTR_ADT
);
176 for (; cb
->args
[2] <= last
; cb
->args
[2]++) {
178 elem
= bitmap_ipmac_elem(map
, id
);
179 if (elem
->match
== MAC_EMPTY
)
181 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
184 nla_nest_cancel(skb
, atd
);
187 goto nla_put_failure
;
189 NLA_PUT_IPADDR4(skb
, IPSET_ATTR_IP
,
190 htonl(map
->first_ip
+ id
));
191 if (elem
->match
== MAC_FILLED
)
192 NLA_PUT(skb
, IPSET_ATTR_ETHER
, ETH_ALEN
,
194 ipset_nest_end(skb
, nested
);
196 ipset_nest_end(skb
, atd
);
197 /* Set listing finished */
203 nla_nest_cancel(skb
, nested
);
204 ipset_nest_end(skb
, atd
);
205 if (unlikely(id
== first
)) {
212 /* Timeout variant */
215 bitmap_ipmac_ttest(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
217 const struct bitmap_ipmac
*map
= set
->data
;
218 const struct ipmac
*data
= value
;
219 const struct ipmac_elem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
221 switch (elem
->match
) {
223 /* Trigger kernel to fill out the ethernet address */
226 return (data
->ether
== NULL
||
227 compare_ether_addr(data
->ether
, elem
->ether
) == 0) &&
228 !bitmap_expired(map
, data
->id
);
234 bitmap_ipmac_tadd(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
236 struct bitmap_ipmac
*map
= set
->data
;
237 const struct ipmac
*data
= value
;
238 struct ipmac_telem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
239 bool flag_exist
= flags
& IPSET_FLAG_EXIST
;
241 switch (elem
->match
) {
243 if (!(data
->ether
|| flag_exist
))
244 /* Already added without ethernet address */
245 return -IPSET_ERR_EXIST
;
246 /* Fill the MAC address and activate the timer */
247 memcpy(elem
->ether
, data
->ether
, ETH_ALEN
);
248 elem
->match
= MAC_FILLED
;
249 if (timeout
== map
->timeout
)
250 /* Timeout was not specified, get stored one */
251 timeout
= elem
->timeout
;
252 elem
->timeout
= ip_set_timeout_set(timeout
);
255 if (!(bitmap_expired(map
, data
->id
) || flag_exist
))
256 return -IPSET_ERR_EXIST
;
260 memcpy(elem
->ether
, data
->ether
, ETH_ALEN
);
261 elem
->match
= MAC_FILLED
;
263 elem
->match
= MAC_UNSET
;
264 /* If MAC is unset yet, we store plain timeout value
265 * because the timer is not activated yet
266 * and we can reuse it later when MAC is filled out,
267 * possibly by the kernel */
268 elem
->timeout
= data
->ether
? ip_set_timeout_set(timeout
)
277 bitmap_ipmac_tdel(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
279 struct bitmap_ipmac
*map
= set
->data
;
280 const struct ipmac
*data
= value
;
281 struct ipmac_telem
*elem
= bitmap_ipmac_elem(map
, data
->id
);
283 if (elem
->match
== MAC_EMPTY
|| bitmap_expired(map
, data
->id
))
284 return -IPSET_ERR_EXIST
;
286 elem
->match
= MAC_EMPTY
;
292 bitmap_ipmac_tlist(const struct ip_set
*set
,
293 struct sk_buff
*skb
, struct netlink_callback
*cb
)
295 const struct bitmap_ipmac
*map
= set
->data
;
296 const struct ipmac_telem
*elem
;
297 struct nlattr
*atd
, *nested
;
298 u32 id
, first
= cb
->args
[2];
299 u32 timeout
, last
= map
->last_ip
- map
->first_ip
;
301 atd
= ipset_nest_start(skb
, IPSET_ATTR_ADT
);
304 for (; cb
->args
[2] <= last
; cb
->args
[2]++) {
306 elem
= bitmap_ipmac_elem(map
, id
);
307 if (!bitmap_ipmac_exist(elem
))
309 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
312 nla_nest_cancel(skb
, atd
);
315 goto nla_put_failure
;
317 NLA_PUT_IPADDR4(skb
, IPSET_ATTR_IP
,
318 htonl(map
->first_ip
+ id
));
319 if (elem
->match
== MAC_FILLED
)
320 NLA_PUT(skb
, IPSET_ATTR_ETHER
, ETH_ALEN
,
322 timeout
= elem
->match
== MAC_UNSET
? elem
->timeout
323 : ip_set_timeout_get(elem
->timeout
);
324 NLA_PUT_NET32(skb
, IPSET_ATTR_TIMEOUT
, htonl(timeout
));
325 ipset_nest_end(skb
, nested
);
327 ipset_nest_end(skb
, atd
);
328 /* Set listing finished */
334 nla_nest_cancel(skb
, nested
);
335 ipset_nest_end(skb
, atd
);
340 bitmap_ipmac_kadt(struct ip_set
*set
, const struct sk_buff
*skb
,
341 const struct xt_action_param
*par
,
342 enum ipset_adt adt
, const struct ip_set_adt_opt
*opt
)
344 struct bitmap_ipmac
*map
= set
->data
;
345 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
348 /* MAC can be src only */
349 if (!(opt
->flags
& IPSET_DIM_TWO_SRC
))
352 data
.id
= ntohl(ip4addr(skb
, opt
->flags
& IPSET_DIM_ONE_SRC
));
353 if (data
.id
< map
->first_ip
|| data
.id
> map
->last_ip
)
354 return -IPSET_ERR_BITMAP_RANGE
;
356 /* Backward compatibility: we don't check the second flag */
357 if (skb_mac_header(skb
) < skb
->head
||
358 (skb_mac_header(skb
) + ETH_HLEN
) > skb
->data
)
361 data
.id
-= map
->first_ip
;
362 data
.ether
= eth_hdr(skb
)->h_source
;
364 return adtfn(set
, &data
, opt_timeout(opt
, map
), opt
->cmdflags
);
368 bitmap_ipmac_uadt(struct ip_set
*set
, struct nlattr
*tb
[],
369 enum ipset_adt adt
, u32
*lineno
, u32 flags
, bool retried
)
371 const struct bitmap_ipmac
*map
= set
->data
;
372 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
374 u32 timeout
= map
->timeout
;
377 if (unlikely(!tb
[IPSET_ATTR_IP
] ||
378 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
)))
379 return -IPSET_ERR_PROTOCOL
;
381 if (tb
[IPSET_ATTR_LINENO
])
382 *lineno
= nla_get_u32(tb
[IPSET_ATTR_LINENO
]);
384 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &data
.id
);
388 if (data
.id
< map
->first_ip
|| data
.id
> map
->last_ip
)
389 return -IPSET_ERR_BITMAP_RANGE
;
391 if (tb
[IPSET_ATTR_ETHER
])
392 data
.ether
= nla_data(tb
[IPSET_ATTR_ETHER
]);
396 if (tb
[IPSET_ATTR_TIMEOUT
]) {
397 if (!with_timeout(map
->timeout
))
398 return -IPSET_ERR_TIMEOUT
;
399 timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
402 data
.id
-= map
->first_ip
;
404 ret
= adtfn(set
, &data
, timeout
, flags
);
406 return ip_set_eexist(ret
, flags
) ? 0 : ret
;
410 bitmap_ipmac_destroy(struct ip_set
*set
)
412 struct bitmap_ipmac
*map
= set
->data
;
414 if (with_timeout(map
->timeout
))
415 del_timer_sync(&map
->gc
);
417 ip_set_free(map
->members
);
424 bitmap_ipmac_flush(struct ip_set
*set
)
426 struct bitmap_ipmac
*map
= set
->data
;
428 memset(map
->members
, 0,
429 (map
->last_ip
- map
->first_ip
+ 1) * map
->dsize
);
433 bitmap_ipmac_head(struct ip_set
*set
, struct sk_buff
*skb
)
435 const struct bitmap_ipmac
*map
= set
->data
;
436 struct nlattr
*nested
;
438 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
440 goto nla_put_failure
;
441 NLA_PUT_IPADDR4(skb
, IPSET_ATTR_IP
, htonl(map
->first_ip
));
442 NLA_PUT_IPADDR4(skb
, IPSET_ATTR_IP_TO
, htonl(map
->last_ip
));
443 NLA_PUT_NET32(skb
, IPSET_ATTR_REFERENCES
, htonl(set
->ref
- 1));
444 NLA_PUT_NET32(skb
, IPSET_ATTR_MEMSIZE
,
446 + (map
->last_ip
- map
->first_ip
+ 1) * map
->dsize
));
447 if (with_timeout(map
->timeout
))
448 NLA_PUT_NET32(skb
, IPSET_ATTR_TIMEOUT
, htonl(map
->timeout
));
449 ipset_nest_end(skb
, nested
);
457 bitmap_ipmac_same_set(const struct ip_set
*a
, const struct ip_set
*b
)
459 const struct bitmap_ipmac
*x
= a
->data
;
460 const struct bitmap_ipmac
*y
= b
->data
;
462 return x
->first_ip
== y
->first_ip
&&
463 x
->last_ip
== y
->last_ip
&&
464 x
->timeout
== y
->timeout
;
467 static const struct ip_set_type_variant bitmap_ipmac
= {
468 .kadt
= bitmap_ipmac_kadt
,
469 .uadt
= bitmap_ipmac_uadt
,
471 [IPSET_ADD
] = bitmap_ipmac_add
,
472 [IPSET_DEL
] = bitmap_ipmac_del
,
473 [IPSET_TEST
] = bitmap_ipmac_test
,
475 .destroy
= bitmap_ipmac_destroy
,
476 .flush
= bitmap_ipmac_flush
,
477 .head
= bitmap_ipmac_head
,
478 .list
= bitmap_ipmac_list
,
479 .same_set
= bitmap_ipmac_same_set
,
482 static const struct ip_set_type_variant bitmap_tipmac
= {
483 .kadt
= bitmap_ipmac_kadt
,
484 .uadt
= bitmap_ipmac_uadt
,
486 [IPSET_ADD
] = bitmap_ipmac_tadd
,
487 [IPSET_DEL
] = bitmap_ipmac_tdel
,
488 [IPSET_TEST
] = bitmap_ipmac_ttest
,
490 .destroy
= bitmap_ipmac_destroy
,
491 .flush
= bitmap_ipmac_flush
,
492 .head
= bitmap_ipmac_head
,
493 .list
= bitmap_ipmac_tlist
,
494 .same_set
= bitmap_ipmac_same_set
,
498 bitmap_ipmac_gc(unsigned long ul_set
)
500 struct ip_set
*set
= (struct ip_set
*) ul_set
;
501 struct bitmap_ipmac
*map
= set
->data
;
502 struct ipmac_telem
*elem
;
503 u32 id
, last
= map
->last_ip
- map
->first_ip
;
505 /* We run parallel with other readers (test element)
506 * but adding/deleting new entries is locked out */
507 read_lock_bh(&set
->lock
);
508 for (id
= 0; id
<= last
; id
++) {
509 elem
= bitmap_ipmac_elem(map
, id
);
510 if (elem
->match
== MAC_FILLED
&&
511 ip_set_timeout_expired(elem
->timeout
))
512 elem
->match
= MAC_EMPTY
;
514 read_unlock_bh(&set
->lock
);
516 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
521 bitmap_ipmac_gc_init(struct ip_set
*set
)
523 struct bitmap_ipmac
*map
= set
->data
;
525 init_timer(&map
->gc
);
526 map
->gc
.data
= (unsigned long) set
;
527 map
->gc
.function
= bitmap_ipmac_gc
;
528 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
532 /* Create bitmap:ip,mac type of sets */
535 init_map_ipmac(struct ip_set
*set
, struct bitmap_ipmac
*map
,
536 u32 first_ip
, u32 last_ip
)
538 map
->members
= ip_set_alloc((last_ip
- first_ip
+ 1) * map
->dsize
);
541 map
->first_ip
= first_ip
;
542 map
->last_ip
= last_ip
;
543 map
->timeout
= IPSET_NO_TIMEOUT
;
546 set
->family
= AF_INET
;
552 bitmap_ipmac_create(struct ip_set
*set
, struct nlattr
*tb
[],
555 u32 first_ip
, last_ip
, elements
;
556 struct bitmap_ipmac
*map
;
559 if (unlikely(!tb
[IPSET_ATTR_IP
] ||
560 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
)))
561 return -IPSET_ERR_PROTOCOL
;
563 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &first_ip
);
567 if (tb
[IPSET_ATTR_IP_TO
]) {
568 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP_TO
], &last_ip
);
571 if (first_ip
> last_ip
) {
577 } else if (tb
[IPSET_ATTR_CIDR
]) {
578 u8 cidr
= nla_get_u8(tb
[IPSET_ATTR_CIDR
]);
581 return -IPSET_ERR_INVALID_CIDR
;
582 ip_set_mask_from_to(first_ip
, last_ip
, cidr
);
584 return -IPSET_ERR_PROTOCOL
;
586 elements
= last_ip
- first_ip
+ 1;
588 if (elements
> IPSET_BITMAP_MAX_RANGE
+ 1)
589 return -IPSET_ERR_BITMAP_RANGE_SIZE
;
591 map
= kzalloc(sizeof(*map
), GFP_KERNEL
);
595 if (tb
[IPSET_ATTR_TIMEOUT
]) {
596 map
->dsize
= sizeof(struct ipmac_telem
);
598 if (!init_map_ipmac(set
, map
, first_ip
, last_ip
)) {
603 map
->timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
605 set
->variant
= &bitmap_tipmac
;
607 bitmap_ipmac_gc_init(set
);
609 map
->dsize
= sizeof(struct ipmac_elem
);
611 if (!init_map_ipmac(set
, map
, first_ip
, last_ip
)) {
615 set
->variant
= &bitmap_ipmac
;
621 static struct ip_set_type bitmap_ipmac_type
= {
622 .name
= "bitmap:ip,mac",
623 .protocol
= IPSET_PROTOCOL
,
624 .features
= IPSET_TYPE_IP
| IPSET_TYPE_MAC
,
625 .dimension
= IPSET_DIM_TWO
,
629 .create
= bitmap_ipmac_create
,
631 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
632 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
633 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
634 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
637 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
638 [IPSET_ATTR_ETHER
] = { .type
= NLA_BINARY
,
640 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
641 [IPSET_ATTR_LINENO
] = { .type
= NLA_U32
},
647 bitmap_ipmac_init(void)
649 return ip_set_type_register(&bitmap_ipmac_type
);
653 bitmap_ipmac_fini(void)
655 ip_set_type_unregister(&bitmap_ipmac_type
);
658 module_init(bitmap_ipmac_init
);
659 module_exit(bitmap_ipmac_fini
);