1 /* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
8 /* Kernel module implementing an IP set type: the bitmap:port type */
10 #include <linux/module.h>
12 #include <linux/skbuff.h>
13 #include <linux/errno.h>
14 #include <linux/netlink.h>
15 #include <linux/jiffies.h>
16 #include <linux/timer.h>
17 #include <net/netlink.h>
19 #include <linux/netfilter/ipset/ip_set.h>
20 #include <linux/netfilter/ipset/ip_set_bitmap.h>
21 #include <linux/netfilter/ipset/ip_set_getport.h>
22 #define IP_SET_BITMAP_TIMEOUT
23 #include <linux/netfilter/ipset/ip_set_timeout.h>
25 MODULE_LICENSE("GPL");
26 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
27 MODULE_DESCRIPTION("bitmap:port type of IP sets");
28 MODULE_ALIAS("ip_set_bitmap:port");
32 void *members
; /* the set members */
33 u16 first_port
; /* host byte order, included in range */
34 u16 last_port
; /* host byte order, included in range */
35 size_t memsize
; /* members size */
36 u32 timeout
; /* timeout parameter */
37 struct timer_list gc
; /* garbage collection */
43 bitmap_port_test(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
45 const struct bitmap_port
*map
= set
->data
;
46 u16 id
= *(u16
*)value
;
48 return !!test_bit(id
, map
->members
);
52 bitmap_port_add(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
54 struct bitmap_port
*map
= set
->data
;
55 u16 id
= *(u16
*)value
;
57 if (test_and_set_bit(id
, map
->members
))
58 return -IPSET_ERR_EXIST
;
64 bitmap_port_del(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
66 struct bitmap_port
*map
= set
->data
;
67 u16 id
= *(u16
*)value
;
69 if (!test_and_clear_bit(id
, map
->members
))
70 return -IPSET_ERR_EXIST
;
76 bitmap_port_list(const struct ip_set
*set
,
77 struct sk_buff
*skb
, struct netlink_callback
*cb
)
79 const struct bitmap_port
*map
= set
->data
;
80 struct nlattr
*atd
, *nested
;
81 u16 id
, first
= cb
->args
[2];
82 u16 last
= map
->last_port
- map
->first_port
;
84 atd
= ipset_nest_start(skb
, IPSET_ATTR_ADT
);
87 for (; cb
->args
[2] <= last
; cb
->args
[2]++) {
89 if (!test_bit(id
, map
->members
))
91 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
94 nla_nest_cancel(skb
, atd
);
99 NLA_PUT_NET16(skb
, IPSET_ATTR_PORT
,
100 htons(map
->first_port
+ id
));
101 ipset_nest_end(skb
, nested
);
103 ipset_nest_end(skb
, atd
);
104 /* Set listing finished */
110 nla_nest_cancel(skb
, nested
);
111 ipset_nest_end(skb
, atd
);
112 if (unlikely(id
== first
)) {
119 /* Timeout variant */
122 bitmap_port_ttest(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
124 const struct bitmap_port
*map
= set
->data
;
125 const unsigned long *members
= map
->members
;
126 u16 id
= *(u16
*)value
;
128 return ip_set_timeout_test(members
[id
]);
132 bitmap_port_tadd(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
134 struct bitmap_port
*map
= set
->data
;
135 unsigned long *members
= map
->members
;
136 u16 id
= *(u16
*)value
;
138 if (ip_set_timeout_test(members
[id
]) && !(flags
& IPSET_FLAG_EXIST
))
139 return -IPSET_ERR_EXIST
;
141 members
[id
] = ip_set_timeout_set(timeout
);
147 bitmap_port_tdel(struct ip_set
*set
, void *value
, u32 timeout
, u32 flags
)
149 struct bitmap_port
*map
= set
->data
;
150 unsigned long *members
= map
->members
;
151 u16 id
= *(u16
*)value
;
152 int ret
= -IPSET_ERR_EXIST
;
154 if (ip_set_timeout_test(members
[id
]))
157 members
[id
] = IPSET_ELEM_UNSET
;
162 bitmap_port_tlist(const struct ip_set
*set
,
163 struct sk_buff
*skb
, struct netlink_callback
*cb
)
165 const struct bitmap_port
*map
= set
->data
;
166 struct nlattr
*adt
, *nested
;
167 u16 id
, first
= cb
->args
[2];
168 u16 last
= map
->last_port
- map
->first_port
;
169 const unsigned long *members
= map
->members
;
171 adt
= ipset_nest_start(skb
, IPSET_ATTR_ADT
);
174 for (; cb
->args
[2] <= last
; cb
->args
[2]++) {
176 if (!ip_set_timeout_test(members
[id
]))
178 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
181 nla_nest_cancel(skb
, adt
);
184 goto nla_put_failure
;
186 NLA_PUT_NET16(skb
, IPSET_ATTR_PORT
,
187 htons(map
->first_port
+ id
));
188 NLA_PUT_NET32(skb
, IPSET_ATTR_TIMEOUT
,
189 htonl(ip_set_timeout_get(members
[id
])));
190 ipset_nest_end(skb
, nested
);
192 ipset_nest_end(skb
, adt
);
194 /* Set listing finished */
200 nla_nest_cancel(skb
, nested
);
201 ipset_nest_end(skb
, adt
);
202 if (unlikely(id
== first
)) {
210 bitmap_port_kadt(struct ip_set
*set
, const struct sk_buff
*skb
,
211 const struct xt_action_param
*par
,
212 enum ipset_adt adt
, const struct ip_set_adt_opt
*opt
)
214 struct bitmap_port
*map
= set
->data
;
215 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
219 if (!ip_set_get_ip_port(skb
, opt
->family
,
220 opt
->flags
& IPSET_DIM_ONE_SRC
, &__port
))
223 port
= ntohs(__port
);
225 if (port
< map
->first_port
|| port
> map
->last_port
)
226 return -IPSET_ERR_BITMAP_RANGE
;
228 port
-= map
->first_port
;
230 return adtfn(set
, &port
, opt_timeout(opt
, map
), opt
->cmdflags
);
234 bitmap_port_uadt(struct ip_set
*set
, struct nlattr
*tb
[],
235 enum ipset_adt adt
, u32
*lineno
, u32 flags
, bool retried
)
237 struct bitmap_port
*map
= set
->data
;
238 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
239 u32 timeout
= map
->timeout
;
240 u32 port
; /* wraparound */
244 if (unlikely(!ip_set_attr_netorder(tb
, IPSET_ATTR_PORT
) ||
245 !ip_set_optattr_netorder(tb
, IPSET_ATTR_PORT_TO
) ||
246 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
)))
247 return -IPSET_ERR_PROTOCOL
;
249 if (tb
[IPSET_ATTR_LINENO
])
250 *lineno
= nla_get_u32(tb
[IPSET_ATTR_LINENO
]);
252 port
= ip_set_get_h16(tb
[IPSET_ATTR_PORT
]);
253 if (port
< map
->first_port
|| port
> map
->last_port
)
254 return -IPSET_ERR_BITMAP_RANGE
;
256 if (tb
[IPSET_ATTR_TIMEOUT
]) {
257 if (!with_timeout(map
->timeout
))
258 return -IPSET_ERR_TIMEOUT
;
259 timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
262 if (adt
== IPSET_TEST
) {
263 id
= port
- map
->first_port
;
264 return adtfn(set
, &id
, timeout
, flags
);
267 if (tb
[IPSET_ATTR_PORT_TO
]) {
268 port_to
= ip_set_get_h16(tb
[IPSET_ATTR_PORT_TO
]);
269 if (port
> port_to
) {
271 if (port
< map
->first_port
)
272 return -IPSET_ERR_BITMAP_RANGE
;
277 if (port_to
> map
->last_port
)
278 return -IPSET_ERR_BITMAP_RANGE
;
280 for (; port
<= port_to
; port
++) {
281 id
= port
- map
->first_port
;
282 ret
= adtfn(set
, &id
, timeout
, flags
);
284 if (ret
&& !ip_set_eexist(ret
, flags
))
293 bitmap_port_destroy(struct ip_set
*set
)
295 struct bitmap_port
*map
= set
->data
;
297 if (with_timeout(map
->timeout
))
298 del_timer_sync(&map
->gc
);
300 ip_set_free(map
->members
);
307 bitmap_port_flush(struct ip_set
*set
)
309 struct bitmap_port
*map
= set
->data
;
311 memset(map
->members
, 0, map
->memsize
);
315 bitmap_port_head(struct ip_set
*set
, struct sk_buff
*skb
)
317 const struct bitmap_port
*map
= set
->data
;
318 struct nlattr
*nested
;
320 nested
= ipset_nest_start(skb
, IPSET_ATTR_DATA
);
322 goto nla_put_failure
;
323 NLA_PUT_NET16(skb
, IPSET_ATTR_PORT
, htons(map
->first_port
));
324 NLA_PUT_NET16(skb
, IPSET_ATTR_PORT_TO
, htons(map
->last_port
));
325 NLA_PUT_NET32(skb
, IPSET_ATTR_REFERENCES
, htonl(set
->ref
- 1));
326 NLA_PUT_NET32(skb
, IPSET_ATTR_MEMSIZE
,
327 htonl(sizeof(*map
) + map
->memsize
));
328 if (with_timeout(map
->timeout
))
329 NLA_PUT_NET32(skb
, IPSET_ATTR_TIMEOUT
, htonl(map
->timeout
));
330 ipset_nest_end(skb
, nested
);
338 bitmap_port_same_set(const struct ip_set
*a
, const struct ip_set
*b
)
340 const struct bitmap_port
*x
= a
->data
;
341 const struct bitmap_port
*y
= b
->data
;
343 return x
->first_port
== y
->first_port
&&
344 x
->last_port
== y
->last_port
&&
345 x
->timeout
== y
->timeout
;
348 static const struct ip_set_type_variant bitmap_port
= {
349 .kadt
= bitmap_port_kadt
,
350 .uadt
= bitmap_port_uadt
,
352 [IPSET_ADD
] = bitmap_port_add
,
353 [IPSET_DEL
] = bitmap_port_del
,
354 [IPSET_TEST
] = bitmap_port_test
,
356 .destroy
= bitmap_port_destroy
,
357 .flush
= bitmap_port_flush
,
358 .head
= bitmap_port_head
,
359 .list
= bitmap_port_list
,
360 .same_set
= bitmap_port_same_set
,
363 static const struct ip_set_type_variant bitmap_tport
= {
364 .kadt
= bitmap_port_kadt
,
365 .uadt
= bitmap_port_uadt
,
367 [IPSET_ADD
] = bitmap_port_tadd
,
368 [IPSET_DEL
] = bitmap_port_tdel
,
369 [IPSET_TEST
] = bitmap_port_ttest
,
371 .destroy
= bitmap_port_destroy
,
372 .flush
= bitmap_port_flush
,
373 .head
= bitmap_port_head
,
374 .list
= bitmap_port_tlist
,
375 .same_set
= bitmap_port_same_set
,
379 bitmap_port_gc(unsigned long ul_set
)
381 struct ip_set
*set
= (struct ip_set
*) ul_set
;
382 struct bitmap_port
*map
= set
->data
;
383 unsigned long *table
= map
->members
;
384 u32 id
; /* wraparound */
385 u16 last
= map
->last_port
- map
->first_port
;
387 /* We run parallel with other readers (test element)
388 * but adding/deleting new entries is locked out */
389 read_lock_bh(&set
->lock
);
390 for (id
= 0; id
<= last
; id
++)
391 if (ip_set_timeout_expired(table
[id
]))
392 table
[id
] = IPSET_ELEM_UNSET
;
393 read_unlock_bh(&set
->lock
);
395 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
400 bitmap_port_gc_init(struct ip_set
*set
)
402 struct bitmap_port
*map
= set
->data
;
404 init_timer(&map
->gc
);
405 map
->gc
.data
= (unsigned long) set
;
406 map
->gc
.function
= bitmap_port_gc
;
407 map
->gc
.expires
= jiffies
+ IPSET_GC_PERIOD(map
->timeout
) * HZ
;
411 /* Create bitmap:ip type of sets */
414 init_map_port(struct ip_set
*set
, struct bitmap_port
*map
,
415 u16 first_port
, u16 last_port
)
417 map
->members
= ip_set_alloc(map
->memsize
);
420 map
->first_port
= first_port
;
421 map
->last_port
= last_port
;
422 map
->timeout
= IPSET_NO_TIMEOUT
;
425 set
->family
= AF_UNSPEC
;
431 bitmap_port_create(struct ip_set
*set
, struct nlattr
*tb
[],
434 struct bitmap_port
*map
;
435 u16 first_port
, last_port
;
437 if (unlikely(!ip_set_attr_netorder(tb
, IPSET_ATTR_PORT
) ||
438 !ip_set_attr_netorder(tb
, IPSET_ATTR_PORT_TO
) ||
439 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
)))
440 return -IPSET_ERR_PROTOCOL
;
442 first_port
= ip_set_get_h16(tb
[IPSET_ATTR_PORT
]);
443 last_port
= ip_set_get_h16(tb
[IPSET_ATTR_PORT_TO
]);
444 if (first_port
> last_port
) {
445 u16 tmp
= first_port
;
447 first_port
= last_port
;
451 map
= kzalloc(sizeof(*map
), GFP_KERNEL
);
455 if (tb
[IPSET_ATTR_TIMEOUT
]) {
456 map
->memsize
= (last_port
- first_port
+ 1)
457 * sizeof(unsigned long);
459 if (!init_map_port(set
, map
, first_port
, last_port
)) {
464 map
->timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
465 set
->variant
= &bitmap_tport
;
467 bitmap_port_gc_init(set
);
469 map
->memsize
= bitmap_bytes(0, last_port
- first_port
);
470 pr_debug("memsize: %zu\n", map
->memsize
);
471 if (!init_map_port(set
, map
, first_port
, last_port
)) {
476 set
->variant
= &bitmap_port
;
481 static struct ip_set_type bitmap_port_type
= {
482 .name
= "bitmap:port",
483 .protocol
= IPSET_PROTOCOL
,
484 .features
= IPSET_TYPE_PORT
,
485 .dimension
= IPSET_DIM_ONE
,
489 .create
= bitmap_port_create
,
491 [IPSET_ATTR_PORT
] = { .type
= NLA_U16
},
492 [IPSET_ATTR_PORT_TO
] = { .type
= NLA_U16
},
493 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
496 [IPSET_ATTR_PORT
] = { .type
= NLA_U16
},
497 [IPSET_ATTR_PORT_TO
] = { .type
= NLA_U16
},
498 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
499 [IPSET_ATTR_LINENO
] = { .type
= NLA_U32
},
505 bitmap_port_init(void)
507 return ip_set_type_register(&bitmap_port_type
);
511 bitmap_port_fini(void)
513 ip_set_type_unregister(&bitmap_port_type
);
516 module_init(bitmap_port_init
);
517 module_exit(bitmap_port_fini
);