1 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2 * Patrick Schaaf <bof@bof.de>
3 * Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
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.
10 /* Kernel module implementing an IP set type: the bitmap:ip type */
12 #include <linux/module.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>
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 #define IP_SET_BITMAP_TIMEOUT
28 #include <linux/netfilter/ipset/ip_set_timeout.h>
30 MODULE_LICENSE("GPL");
31 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
32 MODULE_DESCRIPTION("bitmap:ip type of IP sets");
33 MODULE_ALIAS("ip_set_bitmap:ip");
37 void *members
; /* the set members */
38 u32 first_ip
; /* host byte order, included in range */
39 u32 last_ip
; /* host byte order, included in range */
40 u32 elements
; /* number of max elements in the set */
41 u32 hosts
; /* number of hosts in a subnet */
42 size_t memsize
; /* members size */
43 u8 netmask
; /* subnet netmask */
44 u32 timeout
; /* timeout parameter */
45 struct timer_list gc
; /* garbage collection */
51 ip_to_id(const struct bitmap_ip
*m
, u32 ip
)
53 return ((ip
& ip_set_hostmask(m
->netmask
)) - m
->first_ip
)/m
->hosts
;
57 bitmap_ip_test(struct ip_set
*set
, void *value
, u32 timeout
)
59 const struct bitmap_ip
*map
= set
->data
;
60 u16 id
= *(u16
*)value
;
62 return !!test_bit(id
, map
->members
);
66 bitmap_ip_add(struct ip_set
*set
, void *value
, u32 timeout
)
68 struct bitmap_ip
*map
= set
->data
;
69 u16 id
= *(u16
*)value
;
71 if (test_and_set_bit(id
, map
->members
))
72 return -IPSET_ERR_EXIST
;
78 bitmap_ip_del(struct ip_set
*set
, void *value
, u32 timeout
)
80 struct bitmap_ip
*map
= set
->data
;
81 u16 id
= *(u16
*)value
;
83 if (!test_and_clear_bit(id
, map
->members
))
84 return -IPSET_ERR_EXIST
;
90 bitmap_ip_list(const struct ip_set
*set
,
91 struct sk_buff
*skb
, struct netlink_callback
*cb
)
93 const struct bitmap_ip
*map
= set
->data
;
94 struct nlattr
*atd
, *nested
;
95 u32 id
, first
= cb
->args
[2];
97 atd
= ipset_nest_start(skb
, IPSET_ATTR_ADT
);
100 for (; cb
->args
[2] < map
->elements
; cb
->args
[2]++) {
102 if (!test_bit(id
, map
->members
))
104 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
107 nla_nest_cancel(skb
, atd
);
110 goto nla_put_failure
;
112 NLA_PUT_IPADDR4(skb
, IPSET_ATTR_IP
,
113 htonl(map
->first_ip
+ id
* map
->hosts
));
114 ipset_nest_end(skb
, nested
);
116 ipset_nest_end(skb
, atd
);
117 /* Set listing finished */
122 nla_nest_cancel(skb
, nested
);
123 ipset_nest_end(skb
, atd
);
124 if (unlikely(id
== first
)) {
131 /* Timeout variant */
134 bitmap_ip_ttest(struct ip_set
*set
, void *value
, u32 timeout
)
136 const struct bitmap_ip
*map
= set
->data
;
137 const unsigned long *members
= map
->members
;
138 u16 id
= *(u16
*)value
;
140 return ip_set_timeout_test(members
[id
]);
144 bitmap_ip_tadd(struct ip_set
*set
, void *value
, u32 timeout
)
146 struct bitmap_ip
*map
= set
->data
;
147 unsigned long *members
= map
->members
;
148 u16 id
= *(u16
*)value
;
150 if (ip_set_timeout_test(members
[id
]))
151 return -IPSET_ERR_EXIST
;
153 members
[id
] = ip_set_timeout_set(timeout
);
159 bitmap_ip_tdel(struct ip_set
*set
, void *value
, u32 timeout
)
161 struct bitmap_ip
*map
= set
->data
;
162 unsigned long *members
= map
->members
;
163 u16 id
= *(u16
*)value
;
164 int ret
= -IPSET_ERR_EXIST
;
166 if (ip_set_timeout_test(members
[id
]))
169 members
[id
] = IPSET_ELEM_UNSET
;
174 bitmap_ip_tlist(const struct ip_set
*set
,
175 struct sk_buff
*skb
, struct netlink_callback
*cb
)
177 const struct bitmap_ip
*map
= set
->data
;
178 struct nlattr
*adt
, *nested
;
179 u32 id
, first
= cb
->args
[2];
180 const unsigned long *members
= map
->members
;
182 adt
= ipset_nest_start(skb
, IPSET_ATTR_ADT
);
185 for (; cb
->args
[2] < map
->elements
; cb
->args
[2]++) {
187 if (!ip_set_timeout_test(members
[id
]))
189 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
192 nla_nest_cancel(skb
, adt
);
195 goto nla_put_failure
;
197 NLA_PUT_IPADDR4(skb
, IPSET_ATTR_IP
,
198 htonl(map
->first_ip
+ id
* map
->hosts
));
199 NLA_PUT_NET32(skb
, IPSET_ATTR_TIMEOUT
,
200 htonl(ip_set_timeout_get(members
[id
])));
201 ipset_nest_end(skb
, nested
);
203 ipset_nest_end(skb
, adt
);
205 /* Set listing finished */
211 nla_nest_cancel(skb
, nested
);
212 ipset_nest_end(skb
, adt
);
213 if (unlikely(id
== first
)) {
221 bitmap_ip_kadt(struct ip_set
*set
, const struct sk_buff
*skb
,
222 enum ipset_adt adt
, u8 pf
, u8 dim
, u8 flags
)
224 struct bitmap_ip
*map
= set
->data
;
225 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
228 ip
= ntohl(ip4addr(skb
, flags
& IPSET_DIM_ONE_SRC
));
229 if (ip
< map
->first_ip
|| ip
> map
->last_ip
)
230 return -IPSET_ERR_BITMAP_RANGE
;
232 ip
= ip_to_id(map
, ip
);
234 return adtfn(set
, &ip
, map
->timeout
);
238 bitmap_ip_uadt(struct ip_set
*set
, struct nlattr
*tb
[],
239 enum ipset_adt adt
, u32
*lineno
, u32 flags
)
241 struct bitmap_ip
*map
= set
->data
;
242 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
243 u32 timeout
= map
->timeout
;
247 if (unlikely(!tb
[IPSET_ATTR_IP
] ||
248 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
)))
249 return -IPSET_ERR_PROTOCOL
;
251 if (tb
[IPSET_ATTR_LINENO
])
252 *lineno
= nla_get_u32(tb
[IPSET_ATTR_LINENO
]);
254 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &ip
);
258 if (ip
< map
->first_ip
|| ip
> map
->last_ip
)
259 return -IPSET_ERR_BITMAP_RANGE
;
261 if (tb
[IPSET_ATTR_TIMEOUT
]) {
262 if (!with_timeout(map
->timeout
))
263 return -IPSET_ERR_TIMEOUT
;
264 timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
267 if (adt
== IPSET_TEST
) {
268 id
= ip_to_id(map
, ip
);
269 return adtfn(set
, &id
, timeout
);
272 if (tb
[IPSET_ATTR_IP_TO
]) {
273 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP_TO
], &ip_to
);
278 if (ip
< map
->first_ip
)
279 return -IPSET_ERR_BITMAP_RANGE
;
281 } else if (tb
[IPSET_ATTR_CIDR
]) {
282 u8 cidr
= nla_get_u8(tb
[IPSET_ATTR_CIDR
]);
285 return -IPSET_ERR_INVALID_CIDR
;
286 ip
&= ip_set_hostmask(cidr
);
287 ip_to
= ip
| ~ip_set_hostmask(cidr
);
291 if (ip_to
> map
->last_ip
)
292 return -IPSET_ERR_BITMAP_RANGE
;
294 for (; !before(ip_to
, ip
); ip
+= map
->hosts
) {
295 id
= ip_to_id(map
, ip
);
296 ret
= adtfn(set
, &id
, timeout
);;
298 if (ret
&& !ip_set_eexist(ret
, flags
))
307 bitmap_ip_destroy(struct ip_set
*set
)
309 struct bitmap_ip
*map
= set
->data
;
311 if (with_timeout(map
->timeout
))
312 del_timer_sync(&map
->gc
);
314 ip_set_free(map
->members
);
321 bitmap_ip_flush(struct ip_set
*set
)
323 struct bitmap_ip
*map
= set
->data
;
325 memset(map
->members
, 0, map
->memsize
);
329 bitmap_ip_head(struct ip_set
*set
, struct sk_buff
*skb
)
331 const struct bitmap_ip
*map
= set
->data
;
332 struct nlattr
*nested
;
334 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
336 goto nla_put_failure
;
337 NLA_PUT_IPADDR4(skb
, IPSET_ATTR_IP
, htonl(map
->first_ip
));
338 NLA_PUT_IPADDR4(skb
, IPSET_ATTR_IP_TO
, htonl(map
->last_ip
));
339 if (map
->netmask
!= 32)
340 NLA_PUT_U8(skb
, IPSET_ATTR_NETMASK
, map
->netmask
);
341 NLA_PUT_NET32(skb
, IPSET_ATTR_REFERENCES
, htonl(set
->ref
- 1));
342 NLA_PUT_NET32(skb
, IPSET_ATTR_MEMSIZE
,
343 htonl(sizeof(*map
) + map
->memsize
));
344 if (with_timeout(map
->timeout
))
345 NLA_PUT_NET32(skb
, IPSET_ATTR_TIMEOUT
, htonl(map
->timeout
));
346 ipset_nest_end(skb
, nested
);
354 bitmap_ip_same_set(const struct ip_set
*a
, const struct ip_set
*b
)
356 const struct bitmap_ip
*x
= a
->data
;
357 const struct bitmap_ip
*y
= b
->data
;
359 return x
->first_ip
== y
->first_ip
&&
360 x
->last_ip
== y
->last_ip
&&
361 x
->netmask
== y
->netmask
&&
362 x
->timeout
== y
->timeout
;
365 static const struct ip_set_type_variant bitmap_ip
= {
366 .kadt
= bitmap_ip_kadt
,
367 .uadt
= bitmap_ip_uadt
,
369 [IPSET_ADD
] = bitmap_ip_add
,
370 [IPSET_DEL
] = bitmap_ip_del
,
371 [IPSET_TEST
] = bitmap_ip_test
,
373 .destroy
= bitmap_ip_destroy
,
374 .flush
= bitmap_ip_flush
,
375 .head
= bitmap_ip_head
,
376 .list
= bitmap_ip_list
,
377 .same_set
= bitmap_ip_same_set
,
380 static const struct ip_set_type_variant bitmap_tip
= {
381 .kadt
= bitmap_ip_kadt
,
382 .uadt
= bitmap_ip_uadt
,
384 [IPSET_ADD
] = bitmap_ip_tadd
,
385 [IPSET_DEL
] = bitmap_ip_tdel
,
386 [IPSET_TEST
] = bitmap_ip_ttest
,
388 .destroy
= bitmap_ip_destroy
,
389 .flush
= bitmap_ip_flush
,
390 .head
= bitmap_ip_head
,
391 .list
= bitmap_ip_tlist
,
392 .same_set
= bitmap_ip_same_set
,
396 bitmap_ip_gc(unsigned long ul_set
)
398 struct ip_set
*set
= (struct ip_set
*) ul_set
;
399 struct bitmap_ip
*map
= set
->data
;
400 unsigned long *table
= map
->members
;
403 /* We run parallel with other readers (test element)
404 * but adding/deleting new entries is locked out */
405 read_lock_bh(&set
->lock
);
406 for (id
= 0; id
< map
->elements
; id
++)
407 if (ip_set_timeout_expired(table
[id
]))
408 table
[id
] = IPSET_ELEM_UNSET
;
409 read_unlock_bh(&set
->lock
);
411 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
416 bitmap_ip_gc_init(struct ip_set
*set
)
418 struct bitmap_ip
*map
= set
->data
;
420 init_timer(&map
->gc
);
421 map
->gc
.data
= (unsigned long) set
;
422 map
->gc
.function
= bitmap_ip_gc
;
423 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
427 /* Create bitmap:ip type of sets */
430 init_map_ip(struct ip_set
*set
, struct bitmap_ip
*map
,
431 u32 first_ip
, u32 last_ip
,
432 u32 elements
, u32 hosts
, u8 netmask
)
434 map
->members
= ip_set_alloc(map
->memsize
);
437 map
->first_ip
= first_ip
;
438 map
->last_ip
= last_ip
;
439 map
->elements
= elements
;
441 map
->netmask
= netmask
;
442 map
->timeout
= IPSET_NO_TIMEOUT
;
445 set
->family
= AF_INET
;
451 bitmap_ip_create(struct ip_set
*set
, struct nlattr
*tb
[], u32 flags
)
453 struct bitmap_ip
*map
;
454 u32 first_ip
, last_ip
, hosts
, elements
;
458 if (unlikely(!tb
[IPSET_ATTR_IP
] ||
459 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
)))
460 return -IPSET_ERR_PROTOCOL
;
462 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &first_ip
);
466 if (tb
[IPSET_ATTR_IP_TO
]) {
467 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP_TO
], &last_ip
);
470 if (first_ip
> last_ip
) {
476 } else if (tb
[IPSET_ATTR_CIDR
]) {
477 u8 cidr
= nla_get_u8(tb
[IPSET_ATTR_CIDR
]);
480 return -IPSET_ERR_INVALID_CIDR
;
481 last_ip
= first_ip
| ~ip_set_hostmask(cidr
);
483 return -IPSET_ERR_PROTOCOL
;
485 if (tb
[IPSET_ATTR_NETMASK
]) {
486 netmask
= nla_get_u8(tb
[IPSET_ATTR_NETMASK
]);
489 return -IPSET_ERR_INVALID_NETMASK
;
491 first_ip
&= ip_set_hostmask(netmask
);
492 last_ip
|= ~ip_set_hostmask(netmask
);
497 elements
= last_ip
- first_ip
+ 1;
502 mask
= range_to_mask(first_ip
, last_ip
, &mask_bits
);
504 if ((!mask
&& (first_ip
|| last_ip
!= 0xFFFFFFFF)) ||
505 netmask
<= mask_bits
)
506 return -IPSET_ERR_BITMAP_RANGE
;
508 pr_debug("mask_bits %u, netmask %u\n", mask_bits
, netmask
);
509 hosts
= 2 << (32 - netmask
- 1);
510 elements
= 2 << (netmask
- mask_bits
- 1);
512 if (elements
> IPSET_BITMAP_MAX_RANGE
+ 1)
513 return -IPSET_ERR_BITMAP_RANGE_SIZE
;
515 pr_debug("hosts %u, elements %u\n", hosts
, elements
);
517 map
= kzalloc(sizeof(*map
), GFP_KERNEL
);
521 if (tb
[IPSET_ATTR_TIMEOUT
]) {
522 map
->memsize
= elements
* sizeof(unsigned long);
524 if (!init_map_ip(set
, map
, first_ip
, last_ip
,
525 elements
, hosts
, netmask
)) {
530 map
->timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
531 set
->variant
= &bitmap_tip
;
533 bitmap_ip_gc_init(set
);
535 map
->memsize
= bitmap_bytes(0, elements
- 1);
537 if (!init_map_ip(set
, map
, first_ip
, last_ip
,
538 elements
, hosts
, netmask
)) {
543 set
->variant
= &bitmap_ip
;
548 static struct ip_set_type bitmap_ip_type __read_mostly
= {
550 .protocol
= IPSET_PROTOCOL
,
551 .features
= IPSET_TYPE_IP
,
552 .dimension
= IPSET_DIM_ONE
,
555 .create
= bitmap_ip_create
,
557 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
558 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
559 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
560 [IPSET_ATTR_NETMASK
] = { .type
= NLA_U8
},
561 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
564 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
565 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
566 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
567 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
568 [IPSET_ATTR_LINENO
] = { .type
= NLA_U32
},
576 return ip_set_type_register(&bitmap_ip_type
);
582 ip_set_type_unregister(&bitmap_ip_type
);
585 module_init(bitmap_ip_init
);
586 module_exit(bitmap_ip_fini
);