11 #include <linux/module.h>
14 #include <linux/errno.h>
15 #include <linux/random.h>
21 #include <linux/netfilter.h>
23 #include <linux/netfilter/ipset/ip_set.h>
26 #include <linux/netfilter/ipset/ip_set_hash.h>
28 #define REVISION_MIN 0
29 #define REVISION_MAX 1
37 #define TYPE hash_ipportip
40 hash_ipportip_same_set(
const struct ip_set *
a,
const struct ip_set *
b);
42 #define hash_ipportip4_same_set hash_ipportip_same_set
43 #define hash_ipportip6_same_set hash_ipportip_same_set
71 return ip1->
ip == ip2->
ip &&
80 return elem->
proto == 0;
87 memcpy(dst, src,
sizeof(*dst));
104 goto nla_put_failure;
112 hash_ipportip4_data_tlist(
struct sk_buff *skb,
124 goto nla_put_failure;
144 hash_ipportip4_kadt(
struct ip_set *
set,
const struct sk_buff *skb,
159 return adtfn(
set, &data, opt_timeout(opt, h), opt->
cmdflags);
171 bool with_ports =
false;
181 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
192 data.
port = nla_get_be16(tb[IPSET_ATTR_PORT]);
197 data.
proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
198 with_ports = ip_set_proto_with_ports(data.
proto);
211 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
217 ret = adtfn(
set, &data, timeout, flags);
218 return ip_set_eexist(ret, flags) ? 0 :
ret;
223 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
229 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
231 if (!cidr || cidr > 32)
237 if (with_ports && tb[IPSET_ATTR_PORT_TO]) {
238 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
245 for (; !before(ip_to, ip); ip++) {
248 for (; p <= port_to; p++) {
251 ret = adtfn(
set, &data, timeout, flags);
253 if (ret && !ip_set_eexist(ret, flags))
263 hash_ipportip_same_set(
const struct ip_set *
a,
const struct ip_set *
b)
297 return ipv6_addr_cmp(&ip1->
ip.
in6, &ip2->
ip.
in6) == 0 &&
306 return elem->
proto == 0;
313 memcpy(dst, src,
sizeof(*dst));
323 hash_ipportip6_data_list(
struct sk_buff *skb,
328 nla_put_net16(skb, IPSET_ATTR_PORT, data->
port) ||
329 nla_put_u8(skb, IPSET_ATTR_PROTO, data->
proto))
330 goto nla_put_failure;
338 hash_ipportip6_data_tlist(
struct sk_buff *skb,
346 nla_put_net16(skb, IPSET_ATTR_PORT, data->
port) ||
347 nla_put_u8(skb, IPSET_ATTR_PROTO, data->
proto) ||
348 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
350 goto nla_put_failure;
361 #define HOST_MASK 128
372 hash_ipportip6_kadt(
struct ip_set *
set,
const struct sk_buff *skb,
387 return adtfn(
set, &data, opt_timeout(opt, h), opt->
cmdflags);
391 hash_ipportip6_uadt(
struct ip_set *
set,
struct nlattr *tb[],
399 bool with_ports =
false;
403 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
404 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
405 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
406 tb[IPSET_ATTR_IP_TO] ||
407 tb[IPSET_ATTR_CIDR]))
410 if (tb[IPSET_ATTR_LINENO])
411 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
421 if (tb[IPSET_ATTR_PORT])
422 data.
port = nla_get_be16(tb[IPSET_ATTR_PORT]);
426 if (tb[IPSET_ATTR_PROTO]) {
427 data.
proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
428 with_ports = ip_set_proto_with_ports(data.
proto);
438 if (tb[IPSET_ATTR_TIMEOUT]) {
441 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
444 if (adt ==
IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
445 ret = adtfn(
set, &data, timeout, flags);
446 return ip_set_eexist(ret, flags) ? 0 :
ret;
450 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
456 for (; port <= port_to; port++) {
458 ret = adtfn(
set, &data, timeout, flags);
460 if (ret && !ip_set_eexist(ret, flags))
471 hash_ipportip_create(
struct ip_set *
set,
struct nlattr *tb[],
u32 flags)
483 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
487 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
493 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
503 hbits = htable_bits(hashsize);
504 hsize = htable_size(hbits);
514 h->
table->htable_bits = hbits;
518 if (tb[IPSET_ATTR_TIMEOUT]) {
519 h->
timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
522 ? &hash_ipportip4_tvariant : &hash_ipportip6_tvariant;
525 hash_ipportip4_gc_init(
set);
527 hash_ipportip6_gc_init(
set);
530 ? &hash_ipportip4_variant : &hash_ipportip6_variant;
533 pr_debug(
"create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
541 .name =
"hash:ip,port,ip",
548 .create = hash_ipportip_create,
571 hash_ipportip_init(
void)
577 hash_ipportip_fini(
void)