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
,
342 htonl(atomic_read(&set
->ref
) - 1));
343 NLA_PUT_NET32(skb
, IPSET_ATTR_MEMSIZE
,
344 htonl(sizeof(*map
) + map
->memsize
));
345 if (with_timeout(map
->timeout
))
346 NLA_PUT_NET32(skb
, IPSET_ATTR_TIMEOUT
, htonl(map
->timeout
));
347 ipset_nest_end(skb
, nested
);
355 bitmap_ip_same_set(const struct ip_set
*a
, const struct ip_set
*b
)
357 const struct bitmap_ip
*x
= a
->data
;
358 const struct bitmap_ip
*y
= b
->data
;
360 return x
->first_ip
== y
->first_ip
&&
361 x
->last_ip
== y
->last_ip
&&
362 x
->netmask
== y
->netmask
&&
363 x
->timeout
== y
->timeout
;
366 static const struct ip_set_type_variant bitmap_ip
= {
367 .kadt
= bitmap_ip_kadt
,
368 .uadt
= bitmap_ip_uadt
,
370 [IPSET_ADD
] = bitmap_ip_add
,
371 [IPSET_DEL
] = bitmap_ip_del
,
372 [IPSET_TEST
] = bitmap_ip_test
,
374 .destroy
= bitmap_ip_destroy
,
375 .flush
= bitmap_ip_flush
,
376 .head
= bitmap_ip_head
,
377 .list
= bitmap_ip_list
,
378 .same_set
= bitmap_ip_same_set
,
381 static const struct ip_set_type_variant bitmap_tip
= {
382 .kadt
= bitmap_ip_kadt
,
383 .uadt
= bitmap_ip_uadt
,
385 [IPSET_ADD
] = bitmap_ip_tadd
,
386 [IPSET_DEL
] = bitmap_ip_tdel
,
387 [IPSET_TEST
] = bitmap_ip_ttest
,
389 .destroy
= bitmap_ip_destroy
,
390 .flush
= bitmap_ip_flush
,
391 .head
= bitmap_ip_head
,
392 .list
= bitmap_ip_tlist
,
393 .same_set
= bitmap_ip_same_set
,
397 bitmap_ip_gc(unsigned long ul_set
)
399 struct ip_set
*set
= (struct ip_set
*) ul_set
;
400 struct bitmap_ip
*map
= set
->data
;
401 unsigned long *table
= map
->members
;
404 /* We run parallel with other readers (test element)
405 * but adding/deleting new entries is locked out */
406 read_lock_bh(&set
->lock
);
407 for (id
= 0; id
< map
->elements
; id
++)
408 if (ip_set_timeout_expired(table
[id
]))
409 table
[id
] = IPSET_ELEM_UNSET
;
410 read_unlock_bh(&set
->lock
);
412 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
417 bitmap_ip_gc_init(struct ip_set
*set
)
419 struct bitmap_ip
*map
= set
->data
;
421 init_timer(&map
->gc
);
422 map
->gc
.data
= (unsigned long) set
;
423 map
->gc
.function
= bitmap_ip_gc
;
424 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
428 /* Create bitmap:ip type of sets */
431 init_map_ip(struct ip_set
*set
, struct bitmap_ip
*map
,
432 u32 first_ip
, u32 last_ip
,
433 u32 elements
, u32 hosts
, u8 netmask
)
435 map
->members
= ip_set_alloc(map
->memsize
);
438 map
->first_ip
= first_ip
;
439 map
->last_ip
= last_ip
;
440 map
->elements
= elements
;
442 map
->netmask
= netmask
;
443 map
->timeout
= IPSET_NO_TIMEOUT
;
446 set
->family
= AF_INET
;
452 bitmap_ip_create(struct ip_set
*set
, struct nlattr
*tb
[], u32 flags
)
454 struct bitmap_ip
*map
;
455 u32 first_ip
, last_ip
, hosts
, elements
;
459 if (unlikely(!tb
[IPSET_ATTR_IP
] ||
460 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
)))
461 return -IPSET_ERR_PROTOCOL
;
463 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &first_ip
);
467 if (tb
[IPSET_ATTR_IP_TO
]) {
468 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP_TO
], &last_ip
);
471 if (first_ip
> last_ip
) {
477 } else if (tb
[IPSET_ATTR_CIDR
]) {
478 u8 cidr
= nla_get_u8(tb
[IPSET_ATTR_CIDR
]);
481 return -IPSET_ERR_INVALID_CIDR
;
482 last_ip
= first_ip
| ~ip_set_hostmask(cidr
);
484 return -IPSET_ERR_PROTOCOL
;
486 if (tb
[IPSET_ATTR_NETMASK
]) {
487 netmask
= nla_get_u8(tb
[IPSET_ATTR_NETMASK
]);
490 return -IPSET_ERR_INVALID_NETMASK
;
492 first_ip
&= ip_set_hostmask(netmask
);
493 last_ip
|= ~ip_set_hostmask(netmask
);
498 elements
= last_ip
- first_ip
+ 1;
503 mask
= range_to_mask(first_ip
, last_ip
, &mask_bits
);
505 if ((!mask
&& (first_ip
|| last_ip
!= 0xFFFFFFFF)) ||
506 netmask
<= mask_bits
)
507 return -IPSET_ERR_BITMAP_RANGE
;
509 pr_debug("mask_bits %u, netmask %u\n", mask_bits
, netmask
);
510 hosts
= 2 << (32 - netmask
- 1);
511 elements
= 2 << (netmask
- mask_bits
- 1);
513 if (elements
> IPSET_BITMAP_MAX_RANGE
+ 1)
514 return -IPSET_ERR_BITMAP_RANGE_SIZE
;
516 pr_debug("hosts %u, elements %u\n", hosts
, elements
);
518 map
= kzalloc(sizeof(*map
), GFP_KERNEL
);
522 if (tb
[IPSET_ATTR_TIMEOUT
]) {
523 map
->memsize
= elements
* sizeof(unsigned long);
525 if (!init_map_ip(set
, map
, first_ip
, last_ip
,
526 elements
, hosts
, netmask
)) {
531 map
->timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
532 set
->variant
= &bitmap_tip
;
534 bitmap_ip_gc_init(set
);
536 map
->memsize
= bitmap_bytes(0, elements
- 1);
538 if (!init_map_ip(set
, map
, first_ip
, last_ip
,
539 elements
, hosts
, netmask
)) {
544 set
->variant
= &bitmap_ip
;
549 static struct ip_set_type bitmap_ip_type __read_mostly
= {
551 .protocol
= IPSET_PROTOCOL
,
552 .features
= IPSET_TYPE_IP
,
553 .dimension
= IPSET_DIM_ONE
,
556 .create
= bitmap_ip_create
,
558 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
559 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
560 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
561 [IPSET_ATTR_NETMASK
] = { .type
= NLA_U8
},
562 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
565 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
566 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
567 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
568 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
569 [IPSET_ATTR_LINENO
] = { .type
= NLA_U32
},
577 return ip_set_type_register(&bitmap_ip_type
);
583 ip_set_type_unregister(&bitmap_ip_type
);
586 module_init(bitmap_ip_init
);
587 module_exit(bitmap_ip_fini
);