1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
3 * Patrick Schaaf <bof@bof.de>
4 * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
7 /* Kernel module implementing an IP set type: the bitmap:ip type */
9 #include <linux/module.h>
11 #include <linux/skbuff.h>
12 #include <linux/errno.h>
13 #include <linux/bitops.h>
14 #include <linux/spinlock.h>
15 #include <linux/netlink.h>
16 #include <linux/jiffies.h>
17 #include <linux/timer.h>
18 #include <net/netlink.h>
21 #include <linux/netfilter/ipset/pfxlen.h>
22 #include <linux/netfilter/ipset/ip_set.h>
23 #include <linux/netfilter/ipset/ip_set_bitmap.h>
25 #define IPSET_TYPE_REV_MIN 0
26 /* 1 Counter support added */
27 /* 2 Comment support added */
28 #define IPSET_TYPE_REV_MAX 3 /* skbinfo support added */
30 MODULE_LICENSE("GPL");
31 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
32 IP_SET_MODULE_DESC("bitmap:ip", IPSET_TYPE_REV_MIN
, IPSET_TYPE_REV_MAX
);
33 MODULE_ALIAS("ip_set_bitmap:ip");
35 #define MTYPE bitmap_ip
40 void *members
; /* the set members */
41 u32 first_ip
; /* host byte order, included in range */
42 u32 last_ip
; /* host byte order, included in range */
43 u32 elements
; /* number of max elements in the set */
44 u32 hosts
; /* number of hosts in a subnet */
45 size_t memsize
; /* members size */
46 u8 netmask
; /* subnet netmask */
47 struct timer_list gc
; /* garbage collection */
48 struct ip_set
*set
; /* attached to this ip_set */
49 unsigned char extensions
[0] /* data extensions */
50 __aligned(__alignof__(u64
));
53 /* ADT structure for generic function args */
54 struct bitmap_ip_adt_elem
{
59 ip_to_id(const struct bitmap_ip
*m
, u32 ip
)
61 return ((ip
& ip_set_hostmask(m
->netmask
)) - m
->first_ip
) / m
->hosts
;
64 /* Common functions */
67 bitmap_ip_do_test(const struct bitmap_ip_adt_elem
*e
,
68 struct bitmap_ip
*map
, size_t dsize
)
70 return !!test_bit(e
->id
, map
->members
);
74 bitmap_ip_gc_test(u16 id
, const struct bitmap_ip
*map
, size_t dsize
)
76 return !!test_bit(id
, map
->members
);
80 bitmap_ip_do_add(const struct bitmap_ip_adt_elem
*e
, struct bitmap_ip
*map
,
81 u32 flags
, size_t dsize
)
83 return !!test_bit(e
->id
, map
->members
);
87 bitmap_ip_do_del(const struct bitmap_ip_adt_elem
*e
, struct bitmap_ip
*map
)
89 return !test_and_clear_bit(e
->id
, map
->members
);
93 bitmap_ip_do_list(struct sk_buff
*skb
, const struct bitmap_ip
*map
, u32 id
,
96 return nla_put_ipaddr4(skb
, IPSET_ATTR_IP
,
97 htonl(map
->first_ip
+ id
* map
->hosts
));
101 bitmap_ip_do_head(struct sk_buff
*skb
, const struct bitmap_ip
*map
)
103 return nla_put_ipaddr4(skb
, IPSET_ATTR_IP
, htonl(map
->first_ip
)) ||
104 nla_put_ipaddr4(skb
, IPSET_ATTR_IP_TO
, htonl(map
->last_ip
)) ||
105 (map
->netmask
!= 32 &&
106 nla_put_u8(skb
, IPSET_ATTR_NETMASK
, map
->netmask
));
110 bitmap_ip_kadt(struct ip_set
*set
, const struct sk_buff
*skb
,
111 const struct xt_action_param
*par
,
112 enum ipset_adt adt
, struct ip_set_adt_opt
*opt
)
114 struct bitmap_ip
*map
= set
->data
;
115 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
116 struct bitmap_ip_adt_elem e
= { .id
= 0 };
117 struct ip_set_ext ext
= IP_SET_INIT_KEXT(skb
, opt
, set
);
120 ip
= ntohl(ip4addr(skb
, opt
->flags
& IPSET_DIM_ONE_SRC
));
121 if (ip
< map
->first_ip
|| ip
> map
->last_ip
)
122 return -IPSET_ERR_BITMAP_RANGE
;
124 e
.id
= ip_to_id(map
, ip
);
126 return adtfn(set
, &e
, &ext
, &opt
->ext
, opt
->cmdflags
);
130 bitmap_ip_uadt(struct ip_set
*set
, struct nlattr
*tb
[],
131 enum ipset_adt adt
, u32
*lineno
, u32 flags
, bool retried
)
133 struct bitmap_ip
*map
= set
->data
;
134 ipset_adtfn adtfn
= set
->variant
->adt
[adt
];
135 u32 ip
= 0, ip_to
= 0;
136 struct bitmap_ip_adt_elem e
= { .id
= 0 };
137 struct ip_set_ext ext
= IP_SET_INIT_UEXT(set
);
140 if (tb
[IPSET_ATTR_LINENO
])
141 *lineno
= nla_get_u32(tb
[IPSET_ATTR_LINENO
]);
143 if (unlikely(!tb
[IPSET_ATTR_IP
]))
144 return -IPSET_ERR_PROTOCOL
;
146 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &ip
);
150 ret
= ip_set_get_extensions(set
, tb
, &ext
);
154 if (ip
< map
->first_ip
|| ip
> map
->last_ip
)
155 return -IPSET_ERR_BITMAP_RANGE
;
157 if (adt
== IPSET_TEST
) {
158 e
.id
= ip_to_id(map
, ip
);
159 return adtfn(set
, &e
, &ext
, &ext
, flags
);
162 if (tb
[IPSET_ATTR_IP_TO
]) {
163 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP_TO
], &ip_to
);
168 if (ip
< map
->first_ip
)
169 return -IPSET_ERR_BITMAP_RANGE
;
171 } else if (tb
[IPSET_ATTR_CIDR
]) {
172 u8 cidr
= nla_get_u8(tb
[IPSET_ATTR_CIDR
]);
174 if (!cidr
|| cidr
> HOST_MASK
)
175 return -IPSET_ERR_INVALID_CIDR
;
176 ip_set_mask_from_to(ip
, ip_to
, cidr
);
181 if (ip_to
> map
->last_ip
)
182 return -IPSET_ERR_BITMAP_RANGE
;
184 for (; !before(ip_to
, ip
); ip
+= map
->hosts
) {
185 e
.id
= ip_to_id(map
, ip
);
186 ret
= adtfn(set
, &e
, &ext
, &ext
, flags
);
188 if (ret
&& !ip_set_eexist(ret
, flags
))
197 bitmap_ip_same_set(const struct ip_set
*a
, const struct ip_set
*b
)
199 const struct bitmap_ip
*x
= a
->data
;
200 const struct bitmap_ip
*y
= b
->data
;
202 return x
->first_ip
== y
->first_ip
&&
203 x
->last_ip
== y
->last_ip
&&
204 x
->netmask
== y
->netmask
&&
205 a
->timeout
== b
->timeout
&&
206 a
->extensions
== b
->extensions
;
211 struct bitmap_ip_elem
{
214 #include "ip_set_bitmap_gen.h"
216 /* Create bitmap:ip type of sets */
219 init_map_ip(struct ip_set
*set
, struct bitmap_ip
*map
,
220 u32 first_ip
, u32 last_ip
,
221 u32 elements
, u32 hosts
, u8 netmask
)
223 map
->members
= ip_set_alloc(map
->memsize
);
226 map
->first_ip
= first_ip
;
227 map
->last_ip
= last_ip
;
228 map
->elements
= elements
;
230 map
->netmask
= netmask
;
231 set
->timeout
= IPSET_NO_TIMEOUT
;
235 set
->family
= NFPROTO_IPV4
;
241 bitmap_ip_create(struct net
*net
, struct ip_set
*set
, struct nlattr
*tb
[],
244 struct bitmap_ip
*map
;
245 u32 first_ip
= 0, last_ip
= 0, hosts
;
250 if (unlikely(!tb
[IPSET_ATTR_IP
] ||
251 !ip_set_optattr_netorder(tb
, IPSET_ATTR_TIMEOUT
) ||
252 !ip_set_optattr_netorder(tb
, IPSET_ATTR_CADT_FLAGS
)))
253 return -IPSET_ERR_PROTOCOL
;
255 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP
], &first_ip
);
259 if (tb
[IPSET_ATTR_IP_TO
]) {
260 ret
= ip_set_get_hostipaddr4(tb
[IPSET_ATTR_IP_TO
], &last_ip
);
263 if (first_ip
> last_ip
)
264 swap(first_ip
, last_ip
);
265 } else if (tb
[IPSET_ATTR_CIDR
]) {
266 u8 cidr
= nla_get_u8(tb
[IPSET_ATTR_CIDR
]);
268 if (cidr
>= HOST_MASK
)
269 return -IPSET_ERR_INVALID_CIDR
;
270 ip_set_mask_from_to(first_ip
, last_ip
, cidr
);
272 return -IPSET_ERR_PROTOCOL
;
275 if (tb
[IPSET_ATTR_NETMASK
]) {
276 netmask
= nla_get_u8(tb
[IPSET_ATTR_NETMASK
]);
278 if (netmask
> HOST_MASK
)
279 return -IPSET_ERR_INVALID_NETMASK
;
281 first_ip
&= ip_set_hostmask(netmask
);
282 last_ip
|= ~ip_set_hostmask(netmask
);
287 elements
= (u64
)last_ip
- first_ip
+ 1;
292 mask
= range_to_mask(first_ip
, last_ip
, &mask_bits
);
294 if ((!mask
&& (first_ip
|| last_ip
!= 0xFFFFFFFF)) ||
295 netmask
<= mask_bits
)
296 return -IPSET_ERR_BITMAP_RANGE
;
298 pr_debug("mask_bits %u, netmask %u\n", mask_bits
, netmask
);
299 hosts
= 2 << (32 - netmask
- 1);
300 elements
= 2 << (netmask
- mask_bits
- 1);
302 if (elements
> IPSET_BITMAP_MAX_RANGE
+ 1)
303 return -IPSET_ERR_BITMAP_RANGE_SIZE
;
305 pr_debug("hosts %u, elements %llu\n",
306 hosts
, (unsigned long long)elements
);
308 set
->dsize
= ip_set_elem_len(set
, tb
, 0, 0);
309 map
= ip_set_alloc(sizeof(*map
) + elements
* set
->dsize
);
313 map
->memsize
= bitmap_bytes(0, elements
- 1);
314 set
->variant
= &bitmap_ip
;
315 if (!init_map_ip(set
, map
, first_ip
, last_ip
,
316 elements
, hosts
, netmask
)) {
320 if (tb
[IPSET_ATTR_TIMEOUT
]) {
321 set
->timeout
= ip_set_timeout_uget(tb
[IPSET_ATTR_TIMEOUT
]);
322 bitmap_ip_gc_init(set
, bitmap_ip_gc
);
327 static struct ip_set_type bitmap_ip_type __read_mostly
= {
329 .protocol
= IPSET_PROTOCOL
,
330 .features
= IPSET_TYPE_IP
,
331 .dimension
= IPSET_DIM_ONE
,
332 .family
= NFPROTO_IPV4
,
333 .revision_min
= IPSET_TYPE_REV_MIN
,
334 .revision_max
= IPSET_TYPE_REV_MAX
,
335 .create
= bitmap_ip_create
,
337 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
338 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
339 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
340 [IPSET_ATTR_NETMASK
] = { .type
= NLA_U8
},
341 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
342 [IPSET_ATTR_CADT_FLAGS
] = { .type
= NLA_U32
},
345 [IPSET_ATTR_IP
] = { .type
= NLA_NESTED
},
346 [IPSET_ATTR_IP_TO
] = { .type
= NLA_NESTED
},
347 [IPSET_ATTR_CIDR
] = { .type
= NLA_U8
},
348 [IPSET_ATTR_TIMEOUT
] = { .type
= NLA_U32
},
349 [IPSET_ATTR_LINENO
] = { .type
= NLA_U32
},
350 [IPSET_ATTR_BYTES
] = { .type
= NLA_U64
},
351 [IPSET_ATTR_PACKETS
] = { .type
= NLA_U64
},
352 [IPSET_ATTR_COMMENT
] = { .type
= NLA_NUL_STRING
,
353 .len
= IPSET_MAX_COMMENT_SIZE
},
354 [IPSET_ATTR_SKBMARK
] = { .type
= NLA_U64
},
355 [IPSET_ATTR_SKBPRIO
] = { .type
= NLA_U32
},
356 [IPSET_ATTR_SKBQUEUE
] = { .type
= NLA_U16
},
364 return ip_set_type_register(&bitmap_ip_type
);
371 ip_set_type_unregister(&bitmap_ip_type
);
374 module_init(bitmap_ip_init
);
375 module_exit(bitmap_ip_fini
);