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
, u32 flags
)
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
, u32 flags
)
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
, u32 flags
)
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 if (nla_put_ipaddr4(skb
, IPSET_ATTR_IP
,
113 htonl(map
->first_ip
+ id
* map
->hosts
)))
114 goto nla_put_failure
;
115 ipset_nest_end(skb
, nested
);
117 ipset_nest_end(skb
, atd
);
118 /* Set listing finished */
123 nla_nest_cancel(skb
, nested
);
124 ipset_nest_end(skb
, atd
);
125 if (unlikely(id
== first
)) {
132 /* Timeout variant */
135 bitmap_ip_ttest(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
137 const struct bitmap_ip
*map
= set
->data
;
138 const unsigned long *members
= map
->members
;
139 u16 id
= *(u16
*)value
;
141 return ip_set_timeout_test(members
[id
]);
145 bitmap_ip_tadd(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
147 struct bitmap_ip
*map
= set
->data
;
148 unsigned long *members
= map
->members
;
149 u16 id
= *(u16
*)value
;
151 if (ip_set_timeout_test(members
[id
]) && !(flags
& IPSET_FLAG_EXIST
))
152 return -IPSET_ERR_EXIST
;
154 members
[id
] = ip_set_timeout_set(timeout
);
160 bitmap_ip_tdel(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
162 struct bitmap_ip
*map
= set
->data
;
163 unsigned long *members
= map
->members
;
164 u16 id
= *(u16
*)value
;
165 int ret
= -IPSET_ERR_EXIST
;
167 if (ip_set_timeout_test(members
[id
]))
170 members
[id
] = IPSET_ELEM_UNSET
;
175 bitmap_ip_tlist(const struct ip_set
*set
,
176 struct sk_buff
*skb
, struct netlink_callback
*cb
)
178 const struct bitmap_ip
*map
= set
->data
;
179 struct nlattr
*adt
, *nested
;
180 u32 id
, first
= cb
->args
[2];
181 const unsigned long *members
= map
->members
;
183 adt
= ipset_nest_start(skb
, IPSET_ATTR_ADT
);
186 for (; cb
->args
[2] < map
->elements
; cb
->args
[2]++) {
188 if (!ip_set_timeout_test(members
[id
]))
190 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
193 nla_nest_cancel(skb
, adt
);
196 goto nla_put_failure
;
198 if (nla_put_ipaddr4(skb
, IPSET_ATTR_IP
,
199 htonl(map
->first_ip
+ id
* map
->hosts
)) ||
200 nla_put_net32(skb
, IPSET_ATTR_TIMEOUT
,
201 htonl(ip_set_timeout_get(members
[id
]))))
202 goto nla_put_failure
;
203 ipset_nest_end(skb
, nested
);
205 ipset_nest_end(skb
, adt
);
207 /* Set listing finished */
213 nla_nest_cancel(skb
, nested
);
214 ipset_nest_end(skb
, adt
);
215 if (unlikely(id
== first
)) {
223 bitmap_ip_kadt(struct ip_set
*set
, const struct sk_buff
*skb
,
224 const struct xt_action_param
*par
,
225 enum ipset_adt adt
, const struct ip_set_adt_opt
*opt
)
227 struct bitmap_ip
*map
= set
->data
;
228 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
231 ip
= ntohl(ip4addr(skb
, opt
->flags
& IPSET_DIM_ONE_SRC
));
232 if (ip
< map
->first_ip
|| ip
> map
->last_ip
)
233 return -IPSET_ERR_BITMAP_RANGE
;
235 ip
= ip_to_id(map
, ip
);
237 return adtfn(set
, &ip
, opt_timeout(opt
, map
), opt
->cmdflags
);
241 bitmap_ip_uadt(struct ip_set
*set
, struct nlattr
*tb
[],
242 enum ipset_adt adt
, u32
*lineno
, u32 flags
, bool retried
)
244 struct bitmap_ip
*map
= set
->data
;
245 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
246 u32 timeout
= map
->timeout
;
250 if (unlikely(!tb
[IPSET_ATTR_IP
] ||
251 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
)))
252 return -IPSET_ERR_PROTOCOL
;
254 if (tb
[IPSET_ATTR_LINENO
])
255 *lineno
= nla_get_u32(tb
[IPSET_ATTR_LINENO
]);
257 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &ip
);
261 if (ip
< map
->first_ip
|| ip
> map
->last_ip
)
262 return -IPSET_ERR_BITMAP_RANGE
;
264 if (tb
[IPSET_ATTR_TIMEOUT
]) {
265 if (!with_timeout(map
->timeout
))
266 return -IPSET_ERR_TIMEOUT
;
267 timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
270 if (adt
== IPSET_TEST
) {
271 id
= ip_to_id(map
, ip
);
272 return adtfn(set
, &id
, timeout
, flags
);
275 if (tb
[IPSET_ATTR_IP_TO
]) {
276 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP_TO
], &ip_to
);
281 if (ip
< map
->first_ip
)
282 return -IPSET_ERR_BITMAP_RANGE
;
284 } else if (tb
[IPSET_ATTR_CIDR
]) {
285 u8 cidr
= nla_get_u8(tb
[IPSET_ATTR_CIDR
]);
288 return -IPSET_ERR_INVALID_CIDR
;
289 ip_set_mask_from_to(ip
, ip_to
, cidr
);
293 if (ip_to
> map
->last_ip
)
294 return -IPSET_ERR_BITMAP_RANGE
;
296 for (; !before(ip_to
, ip
); ip
+= map
->hosts
) {
297 id
= ip_to_id(map
, ip
);
298 ret
= adtfn(set
, &id
, timeout
, flags
);
300 if (ret
&& !ip_set_eexist(ret
, flags
))
309 bitmap_ip_destroy(struct ip_set
*set
)
311 struct bitmap_ip
*map
= set
->data
;
313 if (with_timeout(map
->timeout
))
314 del_timer_sync(&map
->gc
);
316 ip_set_free(map
->members
);
323 bitmap_ip_flush(struct ip_set
*set
)
325 struct bitmap_ip
*map
= set
->data
;
327 memset(map
->members
, 0, map
->memsize
);
331 bitmap_ip_head(struct ip_set
*set
, struct sk_buff
*skb
)
333 const struct bitmap_ip
*map
= set
->data
;
334 struct nlattr
*nested
;
336 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
338 goto nla_put_failure
;
339 if (nla_put_ipaddr4(skb
, IPSET_ATTR_IP
, htonl(map
->first_ip
)) ||
340 nla_put_ipaddr4(skb
, IPSET_ATTR_IP_TO
, htonl(map
->last_ip
)) ||
341 (map
->netmask
!= 32 &&
342 nla_put_u8(skb
, IPSET_ATTR_NETMASK
, map
->netmask
)) ||
343 nla_put_net32(skb
, IPSET_ATTR_REFERENCES
, htonl(set
->ref
- 1)) ||
344 nla_put_net32(skb
, IPSET_ATTR_MEMSIZE
,
345 htonl(sizeof(*map
) + map
->memsize
)) ||
346 (with_timeout(map
->timeout
) &&
347 nla_put_net32(skb
, IPSET_ATTR_TIMEOUT
, htonl(map
->timeout
))))
348 goto nla_put_failure
;
349 ipset_nest_end(skb
, nested
);
357 bitmap_ip_same_set(const struct ip_set
*a
, const struct ip_set
*b
)
359 const struct bitmap_ip
*x
= a
->data
;
360 const struct bitmap_ip
*y
= b
->data
;
362 return x
->first_ip
== y
->first_ip
&&
363 x
->last_ip
== y
->last_ip
&&
364 x
->netmask
== y
->netmask
&&
365 x
->timeout
== y
->timeout
;
368 static const struct ip_set_type_variant bitmap_ip
= {
369 .kadt
= bitmap_ip_kadt
,
370 .uadt
= bitmap_ip_uadt
,
372 [IPSET_ADD
] = bitmap_ip_add
,
373 [IPSET_DEL
] = bitmap_ip_del
,
374 [IPSET_TEST
] = bitmap_ip_test
,
376 .destroy
= bitmap_ip_destroy
,
377 .flush
= bitmap_ip_flush
,
378 .head
= bitmap_ip_head
,
379 .list
= bitmap_ip_list
,
380 .same_set
= bitmap_ip_same_set
,
383 static const struct ip_set_type_variant bitmap_tip
= {
384 .kadt
= bitmap_ip_kadt
,
385 .uadt
= bitmap_ip_uadt
,
387 [IPSET_ADD
] = bitmap_ip_tadd
,
388 [IPSET_DEL
] = bitmap_ip_tdel
,
389 [IPSET_TEST
] = bitmap_ip_ttest
,
391 .destroy
= bitmap_ip_destroy
,
392 .flush
= bitmap_ip_flush
,
393 .head
= bitmap_ip_head
,
394 .list
= bitmap_ip_tlist
,
395 .same_set
= bitmap_ip_same_set
,
399 bitmap_ip_gc(unsigned long ul_set
)
401 struct ip_set
*set
= (struct ip_set
*) ul_set
;
402 struct bitmap_ip
*map
= set
->data
;
403 unsigned long *table
= map
->members
;
406 /* We run parallel with other readers (test element)
407 * but adding/deleting new entries is locked out */
408 read_lock_bh(&set
->lock
);
409 for (id
= 0; id
< map
->elements
; id
++)
410 if (ip_set_timeout_expired(table
[id
]))
411 table
[id
] = IPSET_ELEM_UNSET
;
412 read_unlock_bh(&set
->lock
);
414 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
419 bitmap_ip_gc_init(struct ip_set
*set
)
421 struct bitmap_ip
*map
= set
->data
;
423 init_timer(&map
->gc
);
424 map
->gc
.data
= (unsigned long) set
;
425 map
->gc
.function
= bitmap_ip_gc
;
426 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
430 /* Create bitmap:ip type of sets */
433 init_map_ip(struct ip_set
*set
, struct bitmap_ip
*map
,
434 u32 first_ip
, u32 last_ip
,
435 u32 elements
, u32 hosts
, u8 netmask
)
437 map
->members
= ip_set_alloc(map
->memsize
);
440 map
->first_ip
= first_ip
;
441 map
->last_ip
= last_ip
;
442 map
->elements
= elements
;
444 map
->netmask
= netmask
;
445 map
->timeout
= IPSET_NO_TIMEOUT
;
448 set
->family
= NFPROTO_IPV4
;
454 bitmap_ip_create(struct ip_set
*set
, struct nlattr
*tb
[], u32 flags
)
456 struct bitmap_ip
*map
;
457 u32 first_ip
, last_ip
, hosts
, elements
;
461 if (unlikely(!tb
[IPSET_ATTR_IP
] ||
462 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
)))
463 return -IPSET_ERR_PROTOCOL
;
465 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &first_ip
);
469 if (tb
[IPSET_ATTR_IP_TO
]) {
470 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP_TO
], &last_ip
);
473 if (first_ip
> last_ip
) {
479 } else if (tb
[IPSET_ATTR_CIDR
]) {
480 u8 cidr
= nla_get_u8(tb
[IPSET_ATTR_CIDR
]);
483 return -IPSET_ERR_INVALID_CIDR
;
484 ip_set_mask_from_to(first_ip
, last_ip
, cidr
);
486 return -IPSET_ERR_PROTOCOL
;
488 if (tb
[IPSET_ATTR_NETMASK
]) {
489 netmask
= nla_get_u8(tb
[IPSET_ATTR_NETMASK
]);
492 return -IPSET_ERR_INVALID_NETMASK
;
494 first_ip
&= ip_set_hostmask(netmask
);
495 last_ip
|= ~ip_set_hostmask(netmask
);
500 elements
= last_ip
- first_ip
+ 1;
505 mask
= range_to_mask(first_ip
, last_ip
, &mask_bits
);
507 if ((!mask
&& (first_ip
|| last_ip
!= 0xFFFFFFFF)) ||
508 netmask
<= mask_bits
)
509 return -IPSET_ERR_BITMAP_RANGE
;
511 pr_debug("mask_bits %u, netmask %u\n", mask_bits
, netmask
);
512 hosts
= 2 << (32 - netmask
- 1);
513 elements
= 2 << (netmask
- mask_bits
- 1);
515 if (elements
> IPSET_BITMAP_MAX_RANGE
+ 1)
516 return -IPSET_ERR_BITMAP_RANGE_SIZE
;
518 pr_debug("hosts %u, elements %u\n", hosts
, elements
);
520 map
= kzalloc(sizeof(*map
), GFP_KERNEL
);
524 if (tb
[IPSET_ATTR_TIMEOUT
]) {
525 map
->memsize
= elements
* sizeof(unsigned long);
527 if (!init_map_ip(set
, map
, first_ip
, last_ip
,
528 elements
, hosts
, netmask
)) {
533 map
->timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
534 set
->variant
= &bitmap_tip
;
536 bitmap_ip_gc_init(set
);
538 map
->memsize
= bitmap_bytes(0, elements
- 1);
540 if (!init_map_ip(set
, map
, first_ip
, last_ip
,
541 elements
, hosts
, netmask
)) {
546 set
->variant
= &bitmap_ip
;
551 static struct ip_set_type bitmap_ip_type __read_mostly
= {
553 .protocol
= IPSET_PROTOCOL
,
554 .features
= IPSET_TYPE_IP
,
555 .dimension
= IPSET_DIM_ONE
,
556 .family
= NFPROTO_IPV4
,
559 .create
= bitmap_ip_create
,
561 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
562 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
563 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
564 [IPSET_ATTR_NETMASK
] = { .type
= NLA_U8
},
565 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
568 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
569 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
570 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
571 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
572 [IPSET_ATTR_LINENO
] = { .type
= NLA_U32
},
580 return ip_set_type_register(&bitmap_ip_type
);
586 ip_set_type_unregister(&bitmap_ip_type
);
589 module_init(bitmap_ip_init
);
590 module_exit(bitmap_ip_fini
);