1 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2 * Patrick Schaaf <bof@bof.de>
3 * Copyright (C) 2003-2013 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>
28 #define IPSET_TYPE_REV_MIN 0
29 /* 1 Counter support added */
30 /* 2 Comment support added */
31 #define IPSET_TYPE_REV_MAX 3 /* skbinfo support added */
33 MODULE_LICENSE("GPL");
34 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
35 IP_SET_MODULE_DESC("bitmap:ip", IPSET_TYPE_REV_MIN
, IPSET_TYPE_REV_MAX
);
36 MODULE_ALIAS("ip_set_bitmap:ip");
38 #define MTYPE bitmap_ip
43 void *members
; /* the set members */
44 u32 first_ip
; /* host byte order, included in range */
45 u32 last_ip
; /* host byte order, included in range */
46 u32 elements
; /* number of max elements in the set */
47 u32 hosts
; /* number of hosts in a subnet */
48 size_t memsize
; /* members size */
49 u8 netmask
; /* subnet netmask */
50 struct timer_list gc
; /* garbage collection */
51 struct ip_set
*set
; /* attached to this ip_set */
52 unsigned char extensions
[0] /* data extensions */
53 __aligned(__alignof__(u64
));
56 /* ADT structure for generic function args */
57 struct bitmap_ip_adt_elem
{
62 ip_to_id(const struct bitmap_ip
*m
, u32 ip
)
64 return ((ip
& ip_set_hostmask(m
->netmask
)) - m
->first_ip
) / m
->hosts
;
67 /* Common functions */
70 bitmap_ip_do_test(const struct bitmap_ip_adt_elem
*e
,
71 struct bitmap_ip
*map
, size_t dsize
)
73 return !!test_bit(e
->id
, map
->members
);
77 bitmap_ip_gc_test(u16 id
, const struct bitmap_ip
*map
, size_t dsize
)
79 return !!test_bit(id
, map
->members
);
83 bitmap_ip_do_add(const struct bitmap_ip_adt_elem
*e
, struct bitmap_ip
*map
,
84 u32 flags
, size_t dsize
)
86 return !!test_bit(e
->id
, map
->members
);
90 bitmap_ip_do_del(const struct bitmap_ip_adt_elem
*e
, struct bitmap_ip
*map
)
92 return !test_and_clear_bit(e
->id
, map
->members
);
96 bitmap_ip_do_list(struct sk_buff
*skb
, const struct bitmap_ip
*map
, u32 id
,
99 return nla_put_ipaddr4(skb
, IPSET_ATTR_IP
,
100 htonl(map
->first_ip
+ id
* map
->hosts
));
104 bitmap_ip_do_head(struct sk_buff
*skb
, const struct bitmap_ip
*map
)
106 return nla_put_ipaddr4(skb
, IPSET_ATTR_IP
, htonl(map
->first_ip
)) ||
107 nla_put_ipaddr4(skb
, IPSET_ATTR_IP_TO
, htonl(map
->last_ip
)) ||
108 (map
->netmask
!= 32 &&
109 nla_put_u8(skb
, IPSET_ATTR_NETMASK
, map
->netmask
));
113 bitmap_ip_kadt(struct ip_set
*set
, const struct sk_buff
*skb
,
114 const struct xt_action_param
*par
,
115 enum ipset_adt adt
, struct ip_set_adt_opt
*opt
)
117 struct bitmap_ip
*map
= set
->data
;
118 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
119 struct bitmap_ip_adt_elem e
= { .id
= 0 };
120 struct ip_set_ext ext
= IP_SET_INIT_KEXT(skb
, opt
, set
);
123 ip
= ntohl(ip4addr(skb
, opt
->flags
& IPSET_DIM_ONE_SRC
));
124 if (ip
< map
->first_ip
|| ip
> map
->last_ip
)
125 return -IPSET_ERR_BITMAP_RANGE
;
127 e
.id
= ip_to_id(map
, ip
);
129 return adtfn(set
, &e
, &ext
, &opt
->ext
, opt
->cmdflags
);
133 bitmap_ip_uadt(struct ip_set
*set
, struct nlattr
*tb
[],
134 enum ipset_adt adt
, u32
*lineno
, u32 flags
, bool retried
)
136 struct bitmap_ip
*map
= set
->data
;
137 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
138 u32 ip
= 0, ip_to
= 0;
139 struct bitmap_ip_adt_elem e
= { .id
= 0 };
140 struct ip_set_ext ext
= IP_SET_INIT_UEXT(set
);
143 if (tb
[IPSET_ATTR_LINENO
])
144 *lineno
= nla_get_u32(tb
[IPSET_ATTR_LINENO
]);
146 if (unlikely(!tb
[IPSET_ATTR_IP
]))
147 return -IPSET_ERR_PROTOCOL
;
149 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &ip
);
153 ret
= ip_set_get_extensions(set
, tb
, &ext
);
157 if (ip
< map
->first_ip
|| ip
> map
->last_ip
)
158 return -IPSET_ERR_BITMAP_RANGE
;
160 if (adt
== IPSET_TEST
) {
161 e
.id
= ip_to_id(map
, ip
);
162 return adtfn(set
, &e
, &ext
, &ext
, flags
);
165 if (tb
[IPSET_ATTR_IP_TO
]) {
166 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP_TO
], &ip_to
);
171 if (ip
< map
->first_ip
)
172 return -IPSET_ERR_BITMAP_RANGE
;
174 } else if (tb
[IPSET_ATTR_CIDR
]) {
175 u8 cidr
= nla_get_u8(tb
[IPSET_ATTR_CIDR
]);
177 if (!cidr
|| cidr
> HOST_MASK
)
178 return -IPSET_ERR_INVALID_CIDR
;
179 ip_set_mask_from_to(ip
, ip_to
, cidr
);
184 if (ip_to
> map
->last_ip
)
185 return -IPSET_ERR_BITMAP_RANGE
;
187 for (; !before(ip_to
, ip
); ip
+= map
->hosts
) {
188 e
.id
= ip_to_id(map
, ip
);
189 ret
= adtfn(set
, &e
, &ext
, &ext
, flags
);
191 if (ret
&& !ip_set_eexist(ret
, flags
))
200 bitmap_ip_same_set(const struct ip_set
*a
, const struct ip_set
*b
)
202 const struct bitmap_ip
*x
= a
->data
;
203 const struct bitmap_ip
*y
= b
->data
;
205 return x
->first_ip
== y
->first_ip
&&
206 x
->last_ip
== y
->last_ip
&&
207 x
->netmask
== y
->netmask
&&
208 a
->timeout
== b
->timeout
&&
209 a
->extensions
== b
->extensions
;
214 struct bitmap_ip_elem
{
217 #include "ip_set_bitmap_gen.h"
219 /* Create bitmap:ip type of sets */
222 init_map_ip(struct ip_set
*set
, struct bitmap_ip
*map
,
223 u32 first_ip
, u32 last_ip
,
224 u32 elements
, u32 hosts
, u8 netmask
)
226 map
->members
= ip_set_alloc(map
->memsize
);
229 map
->first_ip
= first_ip
;
230 map
->last_ip
= last_ip
;
231 map
->elements
= elements
;
233 map
->netmask
= netmask
;
234 set
->timeout
= IPSET_NO_TIMEOUT
;
238 set
->family
= NFPROTO_IPV4
;
244 bitmap_ip_create(struct net
*net
, struct ip_set
*set
, struct nlattr
*tb
[],
247 struct bitmap_ip
*map
;
248 u32 first_ip
= 0, last_ip
= 0, hosts
;
253 if (unlikely(!tb
[IPSET_ATTR_IP
] ||
254 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
) ||
255 !ip_set_optattr_netorder(tb
, IPSET_ATTR_CADT_FLAGS
)))
256 return -IPSET_ERR_PROTOCOL
;
258 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &first_ip
);
262 if (tb
[IPSET_ATTR_IP_TO
]) {
263 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP_TO
], &last_ip
);
266 if (first_ip
> last_ip
) {
272 } else if (tb
[IPSET_ATTR_CIDR
]) {
273 u8 cidr
= nla_get_u8(tb
[IPSET_ATTR_CIDR
]);
275 if (cidr
>= HOST_MASK
)
276 return -IPSET_ERR_INVALID_CIDR
;
277 ip_set_mask_from_to(first_ip
, last_ip
, cidr
);
279 return -IPSET_ERR_PROTOCOL
;
282 if (tb
[IPSET_ATTR_NETMASK
]) {
283 netmask
= nla_get_u8(tb
[IPSET_ATTR_NETMASK
]);
285 if (netmask
> HOST_MASK
)
286 return -IPSET_ERR_INVALID_NETMASK
;
288 first_ip
&= ip_set_hostmask(netmask
);
289 last_ip
|= ~ip_set_hostmask(netmask
);
294 elements
= (u64
)last_ip
- first_ip
+ 1;
299 mask
= range_to_mask(first_ip
, last_ip
, &mask_bits
);
301 if ((!mask
&& (first_ip
|| last_ip
!= 0xFFFFFFFF)) ||
302 netmask
<= mask_bits
)
303 return -IPSET_ERR_BITMAP_RANGE
;
305 pr_debug("mask_bits %u, netmask %u\n", mask_bits
, netmask
);
306 hosts
= 2 << (32 - netmask
- 1);
307 elements
= 2 << (netmask
- mask_bits
- 1);
309 if (elements
> IPSET_BITMAP_MAX_RANGE
+ 1)
310 return -IPSET_ERR_BITMAP_RANGE_SIZE
;
312 pr_debug("hosts %u, elements %llu\n",
313 hosts
, (unsigned long long)elements
);
315 set
->dsize
= ip_set_elem_len(set
, tb
, 0, 0);
316 map
= ip_set_alloc(sizeof(*map
) + elements
* set
->dsize
);
320 map
->memsize
= bitmap_bytes(0, elements
- 1);
321 set
->variant
= &bitmap_ip
;
322 if (!init_map_ip(set
, map
, first_ip
, last_ip
,
323 elements
, hosts
, netmask
)) {
327 if (tb
[IPSET_ATTR_TIMEOUT
]) {
328 set
->timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
329 bitmap_ip_gc_init(set
, bitmap_ip_gc
);
334 static struct ip_set_type bitmap_ip_type __read_mostly
= {
336 .protocol
= IPSET_PROTOCOL
,
337 .features
= IPSET_TYPE_IP
,
338 .dimension
= IPSET_DIM_ONE
,
339 .family
= NFPROTO_IPV4
,
340 .revision_min
= IPSET_TYPE_REV_MIN
,
341 .revision_max
= IPSET_TYPE_REV_MAX
,
342 .create
= bitmap_ip_create
,
344 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
345 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
346 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
347 [IPSET_ATTR_NETMASK
] = { .type
= NLA_U8
},
348 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
349 [IPSET_ATTR_CADT_FLAGS
] = { .type
= NLA_U32
},
352 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
353 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
354 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
355 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
356 [IPSET_ATTR_LINENO
] = { .type
= NLA_U32
},
357 [IPSET_ATTR_BYTES
] = { .type
= NLA_U64
},
358 [IPSET_ATTR_PACKETS
] = { .type
= NLA_U64
},
359 [IPSET_ATTR_COMMENT
] = { .type
= NLA_NUL_STRING
,
360 .len
= IPSET_MAX_COMMENT_SIZE
},
361 [IPSET_ATTR_SKBMARK
] = { .type
= NLA_U64
},
362 [IPSET_ATTR_SKBPRIO
] = { .type
= NLA_U32
},
363 [IPSET_ATTR_SKBQUEUE
] = { .type
= NLA_U16
},
371 return ip_set_type_register(&bitmap_ip_type
);
378 ip_set_type_unregister(&bitmap_ip_type
);
381 module_init(bitmap_ip_init
);
382 module_exit(bitmap_ip_fini
);