diff --git a/INSTALL b/INSTALL index 1fc1af0..cc1e7ab 100644 --- a/INSTALL +++ b/INSTALL @@ -22,12 +22,6 @@ Supported configurations for this release - CONFIG_CONNECTOR y/m if you wish to receive userspace notifications from pknock through netlink/connector -Compilation of ipset-genl-6.x is disabled by default. It has -additional requirements. - - * libmnl - * Linux kernel >= 2.6.35 - Selecting extensions ==================== diff --git a/README b/README index a2439c0..99fe4a4 100644 --- a/README +++ b/README @@ -18,7 +18,6 @@ simplified, and sped up. Included in this package ======================== -- ipset 6.10-genl - xt_ACCOUNT 1.16, libxt_ACCOUNT 1.3 diff --git a/configure.ac b/configure.ac index 910dcfe..3dbef9c 100644 --- a/configure.ac +++ b/configure.ac @@ -27,7 +27,6 @@ AC_CHECK_HEADERS([linux/netfilter/x_tables.h], [], [AC_MSG_ERROR([You need to have linux/netfilter/x_tables.h, see INSTALL file for details])]) PKG_CHECK_MODULES([libxtables], [xtables >= 1.4.5]) xtlibdir="$(pkg-config --variable=xtlibdir xtables)" -PKG_CHECK_MODULES([libmnl], [libmnl >= 1], [:], [:]) AC_ARG_WITH([xtlibdir], AS_HELP_STRING([--with-xtlibdir=PATH], @@ -81,6 +80,5 @@ AC_SUBST([kbuilddir]) AC_SUBST([xtlibdir]) AC_CONFIG_FILES([Makefile Makefile.iptrules Makefile.mans geoip/Makefile extensions/Makefile extensions/ACCOUNT/Makefile - extensions/ipset-6/Makefile extensions/pknock/Makefile]) AC_OUTPUT diff --git a/doc/changelog.txt b/doc/changelog.txt index c0dd7b5..e304832 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -5,6 +5,9 @@ Fixes: - compat_xtables: fixed mistranslation of checkentry return values (affected kernels < 2.6.23) - xt_SYSRQ: fix compile error when crypto is turned off +Changes: +- ipset6-genl has been dropped from the tree; + the libmnl build-time dependency is thus no longer needed Enhancements: - Support for Linux 3.3, 3.4 diff --git a/extensions/Kbuild b/extensions/Kbuild index 3d23e46..b2b1236 100644 --- a/extensions/Kbuild +++ b/extensions/Kbuild @@ -27,7 +27,6 @@ obj-${build_fuzzy} += xt_fuzzy.o obj-${build_geoip} += xt_geoip.o obj-${build_iface} += xt_iface.o obj-${build_ipp2p} += xt_ipp2p.o -obj-${build_ipset6} += ipset-6/ obj-${build_ipv4options} += xt_ipv4options.o obj-${build_length2} += xt_length2.o obj-${build_lscan} += xt_lscan.o diff --git a/extensions/Mbuild b/extensions/Mbuild index 52f9e9b..1c76e34 100644 --- a/extensions/Mbuild +++ b/extensions/Mbuild @@ -19,7 +19,6 @@ obj-${build_fuzzy} += libxt_fuzzy.so obj-${build_geoip} += libxt_geoip.so obj-${build_iface} += libxt_iface.so obj-${build_ipp2p} += libxt_ipp2p.so -obj-${build_ipset6} += ipset-6/ obj-${build_ipv4options} += libxt_ipv4options.so obj-${build_length2} += libxt_length2.so obj-${build_lscan} += libxt_lscan.so diff --git a/extensions/ipset-6/.gitignore b/extensions/ipset-6/.gitignore deleted file mode 100644 index 6166aba..0000000 --- a/extensions/ipset-6/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/ipset diff --git a/extensions/ipset-6/Kbuild b/extensions/ipset-6/Kbuild deleted file mode 100644 index f54e8a1..0000000 --- a/extensions/ipset-6/Kbuild +++ /dev/null @@ -1,11 +0,0 @@ -# -*- Makefile -*- - -obj-m += xt_set.o -obj-m += ip_set.o ip_set_bitmap_ip.o ip_set_bitmap_ipmac.o -obj-m += ip_set_bitmap_port.o ip_set_hash_ip.o ip_set_hash_ipport.o -obj-m += ip_set_hash_ipportip.o ip_set_hash_ipportnet.o ip_set_hash_net.o -obj-m += ip_set_hash_netiface.o ip_set_hash_netport.o ip_set_list_set.o - -ip_set-y := ip_set_core.o ip_set_getport.o pfxlen.o - -EXTRA_CFLAGS += -DLCONFIG_IP_SET_MAX=256 diff --git a/extensions/ipset-6/Makefile.am b/extensions/ipset-6/Makefile.am deleted file mode 100644 index 8ab5ab1..0000000 --- a/extensions/ipset-6/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# -*- Makefile -*- - -AM_CPPFLAGS = -I${srcdir}/include -DNDEBUG -AM_CFLAGS = ${regular_CFLAGS} ${libmnl_CFLAGS} - -include ../../Makefile.extra - -lib_LTLIBRARIES = libipset.la -libipset_la_SOURCES = libipset/data.c libipset/icmp.c libipset/icmpv6.c \ - libipset/mnl.c libipset/parse.c libipset/print.c \ - libipset/session.c libipset/types.c libipset/errcode.c -libipset_la_LIBADD = ${libmnl_LIBS} -libipset_la_LDFLAGS = -version-info 1:0:0 - -sbin_PROGRAMS = ipset -ipset_SOURCES = src/ipset.c src/ui.c src/ipset_bitmap_ip.c \ - src/ipset_bitmap_ipmac.c src/ipset_bitmap_port.c \ - src/ipset_hash_ip.c src/ipset_hash_ipport.c \ - src/ipset_hash_ipportip.c src/ipset_hash_ipportnet.c \ - src/ipset_hash_net.c src/ipset_hash_netiface.c \ - src/ipset_hash_netport.c \ - src/ipset_list_set.c -ipset_LDADD = libipset.la - -man_MANS = src/ipset.8 diff --git a/extensions/ipset-6/Mbuild b/extensions/ipset-6/Mbuild deleted file mode 100644 index 8a69de2..0000000 --- a/extensions/ipset-6/Mbuild +++ /dev/null @@ -1,2 +0,0 @@ -# -*- Makefile -*- - diff --git a/extensions/ipset-6/README b/extensions/ipset-6/README deleted file mode 100644 index a7ef16c..0000000 --- a/extensions/ipset-6/README +++ /dev/null @@ -1,88 +0,0 @@ -This is the ipset source tree. Follow the next steps to install ipset. -If you upgrade from an earlier 5.x release, please read the UPGRADE -instructions too. - -0. You need the source tree of your kernel (version >= 2.6.34) - and it have to be configured with ip6tables support enabled, - modules compiled. Please apply the netlink.patch against your kernel - tree, which adds the new subsystem identifier for ipset. - - Recompile and install the patched kernel and its modules. Please note, - you have to run the patched kernel for ipset to work. - - The ipset source code depends on the libmnl library so the library - must be installed. You can download the libmnl library from - - git://git.netfilter.org/libmnl.git - -1. Initialize the compiling environment for ipset. The packages automake, - autoconf and libtool are required. - - % ./autogen.sh - -2. Run `./configure` and then compile the ipset binary and the kernel - modules. - - Configure parameters can be used to to override the default path - to the kernel source tree (/lib/modules/`uname -r`/build), - the maximum number of sets (256), the default hash sizes (1024). - See `./configure --help`. - - % ./configure - % make - % make modules - -3. Install the binary and the kernel modules - - # make install - # make modules_install - - After installing the modules, you can run the testsuite as well. - Please note, several assumptions must be met for the testsuite: - - - no sets defined - - iptables/ip6tables rules are not set up - - the destination for kernel logs is /var/log/kern.log - - the networks 10.255.255.0/24 and 1002:1002:1002:1002::/64 - are not in use - - sendip utility is installed - - # make tests - -4. Cleanup the source tree - - % make clean - % make modules_clean - -That's it! - -Read the ipset(8) and iptables(8), ip6tables(8) manpages on how to use -ipset and its match and target from iptables. - -Compatibilities and incompatibilities: - -- The ipset 6.x userspace utility contains a backward compatibility - interface to support the commandline syntax of ipset 4.x. - The commandline syntax of ipset 6.x is fully compatible with 5.x. -- The ipset 6.x userspace utility can't talk to the kernel part of ipset 5.x - or 4.x. -- The ipset 6.x kernel part can't talk to the userspace utility from - ipset 5.x or 4.x. -- The ipset 6.x kernel part can work together with the set match and SET - target from iptables 1.4.7 and below, however if you need the IPv6 support - from ipset 6.x, then you have to use iptables 1.4.8 or above. - -The ipset 6.x can interpret the commandline syntax of ipset 4.x, however -some internal changes mean different behaviour: - -- The "--matchunset" flag for the macipmap type is ignored and not used - anymore. -- The "--probes" and "--resize" parameters of the hash types are ignored - and not used anymore. -- The "--from", "--to" and "--network" parameters of the ipporthash, - ipportiphash and ipportnethash types are ignored and not used anymore. -- The hash types are not resized when new entries are added by the SET - target. If you use a set together with the SET target, create it with - the proper size because it won't be resized automatically. -- The iptree, iptreemap types are not implemented in ipset 6.x. The types - are automatically substituted with the hash:ip type. diff --git a/extensions/ipset-6/VERSION.txt b/extensions/ipset-6/VERSION.txt deleted file mode 100644 index ecb326e..0000000 --- a/extensions/ipset-6/VERSION.txt +++ /dev/null @@ -1 +0,0 @@ -5.4.1-genl diff --git a/extensions/ipset-6/include/libipset/data.h b/extensions/ipset-6/include/libipset/data.h deleted file mode 100644 index 3ba6f0a..0000000 --- a/extensions/ipset-6/include/libipset/data.h +++ /dev/null @@ -1,138 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_DATA_H -#define LIBIPSET_DATA_H - -#include /* bool */ -#include /* union nf_inet_addr */ - -/* Data options */ -enum ipset_opt { - IPSET_OPT_NONE = 0, - /* Common ones */ - IPSET_SETNAME, - IPSET_OPT_TYPENAME, - IPSET_OPT_FAMILY, - /* CADT options */ - IPSET_OPT_IP, - IPSET_OPT_IP_FROM = IPSET_OPT_IP, - IPSET_OPT_IP_TO, - IPSET_OPT_CIDR, - IPSET_OPT_PORT, - IPSET_OPT_PORT_FROM = IPSET_OPT_PORT, - IPSET_OPT_PORT_TO, - IPSET_OPT_TIMEOUT, - /* Create-specific options */ - IPSET_OPT_GC, - IPSET_OPT_HASHSIZE, - IPSET_OPT_MAXELEM, - IPSET_OPT_NETMASK, - IPSET_OPT_PROBES, - IPSET_OPT_RESIZE, - IPSET_OPT_SIZE, - /* Create-specific options, filled out by the kernel */ - IPSET_OPT_ELEMENTS, - IPSET_OPT_REFERENCES, - IPSET_OPT_MEMSIZE, - /* ADT-specific options */ - IPSET_OPT_ETHER, - IPSET_OPT_NAME, - IPSET_OPT_NAMEREF, - IPSET_OPT_IP2, - IPSET_OPT_CIDR2, - IPSET_OPT_IP2_TO, - IPSET_OPT_PROTO, - IPSET_OPT_IFACE, - /* Swap/rename to */ - IPSET_OPT_SETNAME2, - /* Flags */ - IPSET_OPT_EXIST, - IPSET_OPT_BEFORE, - IPSET_OPT_PHYSDEV, - /* Internal options */ - IPSET_OPT_FLAGS = 48, /* IPSET_FLAG_EXIST| */ - IPSET_OPT_CADT_FLAGS, /* IPSET_FLAG_BEFORE| */ - IPSET_OPT_ELEM, - IPSET_OPT_TYPE, - IPSET_OPT_LINENO, - IPSET_OPT_REVISION, - IPSET_OPT_REVISION_MIN, - IPSET_OPT_MAX, -}; - -#define IPSET_FLAG(opt) (1LL << (opt)) -#define IPSET_FLAGS_ALL (~0LL) - -#define IPSET_CREATE_FLAGS \ - (IPSET_FLAG(IPSET_OPT_FAMILY) \ - | IPSET_FLAG(IPSET_OPT_TYPENAME)\ - | IPSET_FLAG(IPSET_OPT_TYPE) \ - | IPSET_FLAG(IPSET_OPT_IP) \ - | IPSET_FLAG(IPSET_OPT_IP_TO) \ - | IPSET_FLAG(IPSET_OPT_CIDR) \ - | IPSET_FLAG(IPSET_OPT_PORT) \ - | IPSET_FLAG(IPSET_OPT_PORT_TO) \ - | IPSET_FLAG(IPSET_OPT_TIMEOUT) \ - | IPSET_FLAG(IPSET_OPT_GC) \ - | IPSET_FLAG(IPSET_OPT_HASHSIZE)\ - | IPSET_FLAG(IPSET_OPT_MAXELEM) \ - | IPSET_FLAG(IPSET_OPT_NETMASK) \ - | IPSET_FLAG(IPSET_OPT_PROBES) \ - | IPSET_FLAG(IPSET_OPT_RESIZE) \ - | IPSET_FLAG(IPSET_OPT_SIZE)) - -#define IPSET_ADT_FLAGS \ - (IPSET_FLAG(IPSET_OPT_IP) \ - | IPSET_FLAG(IPSET_OPT_IP_TO) \ - | IPSET_FLAG(IPSET_OPT_CIDR) \ - | IPSET_FLAG(IPSET_OPT_PORT) \ - | IPSET_FLAG(IPSET_OPT_PORT_TO) \ - | IPSET_FLAG(IPSET_OPT_TIMEOUT) \ - | IPSET_FLAG(IPSET_OPT_ETHER) \ - | IPSET_FLAG(IPSET_OPT_NAME) \ - | IPSET_FLAG(IPSET_OPT_NAMEREF) \ - | IPSET_FLAG(IPSET_OPT_IP2) \ - | IPSET_FLAG(IPSET_OPT_CIDR2) \ - | IPSET_FLAG(IPSET_OPT_PROTO) \ - | IPSET_FLAG(IPSET_OPT_IFACE) \ - | IPSET_FLAG(IPSET_OPT_CADT_FLAGS)\ - | IPSET_FLAG(IPSET_OPT_BEFORE) \ - | IPSET_FLAG(IPSET_OPT_PHYSDEV)) - -struct ipset_data; - -extern void ipset_strlcpy(char *dst, const char *src, size_t len); -extern bool ipset_data_flags_test(const struct ipset_data *data, - uint64_t flags); -extern void ipset_data_flags_set(struct ipset_data *data, uint64_t flags); -extern void ipset_data_flags_unset(struct ipset_data *data, uint64_t flags); -extern bool ipset_data_ignored(struct ipset_data *data, enum ipset_opt opt); - -extern int ipset_data_set(struct ipset_data *data, enum ipset_opt opt, - const void *value); -extern const void *ipset_data_get(const struct ipset_data *data, - enum ipset_opt opt); - -static inline bool -ipset_data_test(const struct ipset_data *data, enum ipset_opt opt) -{ - return ipset_data_flags_test(data, IPSET_FLAG(opt)); -} - -/* Shortcuts */ -extern const char *ipset_data_setname(const struct ipset_data *data); -extern uint8_t ipset_data_family(const struct ipset_data *data); -extern uint8_t ipset_data_cidr(const struct ipset_data *data); -extern uint64_t ipset_data_flags(const struct ipset_data *data); - -extern void ipset_data_reset(struct ipset_data *data); -extern struct ipset_data *ipset_data_init(void); -extern void ipset_data_fini(struct ipset_data *data); - -extern size_t ipset_data_sizeof(enum ipset_opt opt, uint8_t family); - -#endif /* LIBIPSET_DATA_H */ diff --git a/extensions/ipset-6/include/libipset/debug.h b/extensions/ipset-6/include/libipset/debug.h deleted file mode 100644 index b9d5479..0000000 --- a/extensions/ipset-6/include/libipset/debug.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_DEBUG_H -#define LIBIPSET_DEBUG_H - -#ifdef IPSET_DEBUG -#include -#include -#include -#define D(fmt, args...) \ - fprintf(stderr, "%s: %s: " fmt "\n", __FILE__, __func__ , ## args) -#define IF_D(test, fmt, args...) \ - if (test) \ - D(fmt , ## args) - -static inline void -dump_nla(struct nlattr *nla[], int maxlen) -{ - int i; - for (i = 0; i < maxlen; i++) - D("nla[%u] does%s exist", i, nla[i] ? "" : " NOT"); -} -#else -#define D(fmt, args...) -#define IF_D(test, fmt, args...) -#define dump_nla(nla, maxlen) -#endif - -#endif /* LIBIPSET_DEBUG_H */ diff --git a/extensions/ipset-6/include/libipset/errcode.h b/extensions/ipset-6/include/libipset/errcode.h deleted file mode 100644 index 1593d89..0000000 --- a/extensions/ipset-6/include/libipset/errcode.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright 2007-2008 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_ERRCODE_H -#define LIBIPSET_ERRCODE_H - -#include /* enum ipset_cmd */ - -struct ipset_session; - -/* Kernel error code to message table */ -struct ipset_errcode_table { - int errcode; /* error code returned by the kernel */ - enum ipset_cmd cmd; /* issued command */ - const char *message; /* error message the code translated to */ -}; - -extern int ipset_errcode(struct ipset_session *session, enum ipset_cmd cmd, - int errcode); - -#endif /* LIBIPSET_ERRCODE_H */ diff --git a/extensions/ipset-6/include/libipset/icmp.h b/extensions/ipset-6/include/libipset/icmp.h deleted file mode 100644 index e27fd4a..0000000 --- a/extensions/ipset-6/include/libipset/icmp.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_ICMP_H -#define LIBIPSET_ICMP_H - -#include /* uintxx_t */ - -extern const char *id_to_icmp(uint8_t id); -extern const char *icmp_to_name(uint8_t type, uint8_t code); -extern int name_to_icmp(const char *str, uint16_t *typecode); - -#endif /* LIBIPSET_ICMP_H */ diff --git a/extensions/ipset-6/include/libipset/icmpv6.h b/extensions/ipset-6/include/libipset/icmpv6.h deleted file mode 100644 index 8295445..0000000 --- a/extensions/ipset-6/include/libipset/icmpv6.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_ICMPV6_H -#define LIBIPSET_ICMPV6_H - -#include /* uintxx_t */ - -extern const char *id_to_icmpv6(uint8_t id); -extern const char *icmpv6_to_name(uint8_t type, uint8_t code); -extern int name_to_icmpv6(const char *str, uint16_t *typecode); - -#endif /* LIBIPSET_ICMPV6_H */ diff --git a/extensions/ipset-6/include/libipset/linux_ip_set.h b/extensions/ipset-6/include/libipset/linux_ip_set.h deleted file mode 100644 index b601b96..0000000 --- a/extensions/ipset-6/include/libipset/linux_ip_set.h +++ /dev/null @@ -1,199 +0,0 @@ -#ifndef _IP_SET_H -#define _IP_SET_H - -/* Copyright (C) 2000-2002 Joakim Axelsson - * Patrick Schaaf - * Martin Josefsson - * Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include - -/* The protocol version */ -#define IPSET_PROTOCOL 0x60 - -/* The max length of strings including NUL: set and type identifiers */ -#define IPSET_MAXNAMELEN 32 - -/* Message types and commands */ -enum ipset_cmd { - IPSET_CMD_NONE, - IPSET_CMD_PROTOCOL, /* 1: Return protocol version */ - IPSET_CMD_CREATE, /* 2: Create a new (empty) set */ - IPSET_CMD_DESTROY, /* 3: Destroy a (empty) set */ - IPSET_CMD_FLUSH, /* 4: Remove all elements from a set */ - IPSET_CMD_RENAME, /* 5: Rename a set */ - IPSET_CMD_SWAP, /* 6: Swap two sets */ - IPSET_CMD_LIST, /* 7: List sets */ - IPSET_CMD_SAVE, /* 8: Save sets */ - IPSET_CMD_ADD, /* 9: Add an element to a set */ - IPSET_CMD_DEL, /* 10: Delete an element from a set */ - IPSET_CMD_TEST, /* 11: Test an element in a set */ - IPSET_CMD_HEADER, /* 12: Get set header data only */ - IPSET_CMD_TYPE, /* 13: Get set type */ - IPSET_MSG_MAX, /* Netlink message commands */ - - /* Commands in userspace: */ - IPSET_CMD_RESTORE = IPSET_MSG_MAX, /* 14: Enter restore mode */ - IPSET_CMD_HELP, /* 15: Get help */ - IPSET_CMD_VERSION, /* 16: Get program version */ - IPSET_CMD_QUIT, /* 17: Quit from interactive mode */ - - IPSET_CMD_MAX, - - IPSET_CMD_COMMIT = IPSET_CMD_MAX, /* 18: Commit buffered commands */ -}; - -/* Attributes at command level */ -enum { - IPSET_ATTR_UNSPEC, - IPSET_ATTR_PROTOCOL, /* 1: Protocol version */ - IPSET_ATTR_SETNAME, /* 2: Name of the set */ - IPSET_ATTR_TYPENAME, /* 3: Typename */ - IPSET_ATTR_SETNAME2 = IPSET_ATTR_TYPENAME, /* Setname at rename/swap */ - IPSET_ATTR_REVISION, /* 4: Settype revision */ - IPSET_ATTR_FAMILY, /* 5: Settype family */ - IPSET_ATTR_FLAGS, /* 6: Flags at command level */ - IPSET_ATTR_DATA, /* 7: Nested attributes */ - IPSET_ATTR_ADT, /* 8: Multiple data containers */ - IPSET_ATTR_LINENO, /* 9: Restore lineno */ - IPSET_ATTR_PROTOCOL_MIN, /* 10: Minimal supported version number */ - IPSET_ATTR_REVISION_MIN = IPSET_ATTR_PROTOCOL_MIN, /* type rev min */ - __IPSET_ATTR_CMD_MAX, -}; -#define IPSET_ATTR_CMD_MAX (__IPSET_ATTR_CMD_MAX - 1) - -/* CADT specific attributes */ -enum { - IPSET_ATTR_IP = IPSET_ATTR_UNSPEC + 1, - IPSET_ATTR_IP_FROM = IPSET_ATTR_IP, - IPSET_ATTR_IP_TO, /* 2 */ - IPSET_ATTR_CIDR, /* 3 */ - IPSET_ATTR_PORT, /* 4 */ - IPSET_ATTR_PORT_FROM = IPSET_ATTR_PORT, - IPSET_ATTR_PORT_TO, /* 5 */ - IPSET_ATTR_TIMEOUT, /* 6 */ - IPSET_ATTR_PROTO, /* 7 */ - IPSET_ATTR_CADT_FLAGS, /* 8 */ - IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO, /* 9 */ - /* Reserve empty slots */ - IPSET_ATTR_CADT_MAX = 16, - /* Create-only specific attributes */ - IPSET_ATTR_GC, - IPSET_ATTR_HASHSIZE, - IPSET_ATTR_MAXELEM, - IPSET_ATTR_NETMASK, - IPSET_ATTR_PROBES, - IPSET_ATTR_RESIZE, - IPSET_ATTR_SIZE, - /* Kernel-only */ - IPSET_ATTR_ELEMENTS, - IPSET_ATTR_REFERENCES, - IPSET_ATTR_MEMSIZE, - - __IPSET_ATTR_CREATE_MAX, -}; -#define IPSET_ATTR_CREATE_MAX (__IPSET_ATTR_CREATE_MAX - 1) - -/* ADT specific attributes */ -enum { - IPSET_ATTR_ETHER = IPSET_ATTR_CADT_MAX + 1, - IPSET_ATTR_NAME, - IPSET_ATTR_NAMEREF, - IPSET_ATTR_IP2, - IPSET_ATTR_CIDR2, - IPSET_ATTR_IP2_TO, - IPSET_ATTR_IFACE, - __IPSET_ATTR_ADT_MAX, -}; -#define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1) - -/* IP specific attributes */ -enum { - IPSET_ATTR_IPADDR_IPV4 = IPSET_ATTR_UNSPEC + 1, - IPSET_ATTR_IPADDR_IPV6, - __IPSET_ATTR_IPADDR_MAX, -}; -#define IPSET_ATTR_IPADDR_MAX (__IPSET_ATTR_IPADDR_MAX - 1) - -/* Error codes */ -enum ipset_errno { - IPSET_ERR_PRIVATE = 4096, - IPSET_ERR_PROTOCOL, - IPSET_ERR_FIND_TYPE, - IPSET_ERR_MAX_SETS, - IPSET_ERR_BUSY, - IPSET_ERR_EXIST_SETNAME2, - IPSET_ERR_TYPE_MISMATCH, - IPSET_ERR_EXIST, - IPSET_ERR_INVALID_CIDR, - IPSET_ERR_INVALID_NETMASK, - IPSET_ERR_INVALID_FAMILY, - IPSET_ERR_TIMEOUT, - IPSET_ERR_REFERENCED, - IPSET_ERR_IPADDR_IPV4, - IPSET_ERR_IPADDR_IPV6, - - /* Type specific error codes */ - IPSET_ERR_TYPE_SPECIFIC = 4352, -}; - -/* Flags at command level */ -enum ipset_cmd_flags { - IPSET_FLAG_BIT_EXIST = 0, - IPSET_FLAG_EXIST = (1 << IPSET_FLAG_BIT_EXIST), - IPSET_FLAG_BIT_LIST_SETNAME = 1, - IPSET_FLAG_LIST_SETNAME = (1 << IPSET_FLAG_BIT_LIST_SETNAME), - IPSET_FLAG_BIT_LIST_HEADER = 2, - IPSET_FLAG_LIST_HEADER = (1 << IPSET_FLAG_BIT_LIST_HEADER), -}; - -/* Flags at CADT attribute level */ -enum ipset_cadt_flags { - IPSET_FLAG_BIT_BEFORE = 0, - IPSET_FLAG_BEFORE = (1 << IPSET_FLAG_BIT_BEFORE), - IPSET_FLAG_BIT_PHYSDEV = 1, - IPSET_FLAG_PHYSDEV = (1 << IPSET_FLAG_BIT_PHYSDEV), -}; - -/* Commands with settype-specific attributes */ -enum ipset_adt { - IPSET_ADD, - IPSET_DEL, - IPSET_TEST, - IPSET_ADT_MAX, - IPSET_CREATE = IPSET_ADT_MAX, - IPSET_CADT_MAX, -}; - -/* Sets are identified by an index in kernel space. Tweak with ip_set_id_t - * and IPSET_INVALID_ID if you want to increase the max number of sets. - */ -typedef __u16 ip_set_id_t; - -#define IPSET_INVALID_ID 65535 - -enum ip_set_dim { - IPSET_DIM_ZERO = 0, - IPSET_DIM_ONE, - IPSET_DIM_TWO, - IPSET_DIM_THREE, - /* Max dimension in elements. - * If changed, new revision of iptables match/target is required. - */ - IPSET_DIM_MAX = 6, -}; - -/* Option flags for kernel operations */ -enum ip_set_kopt { - IPSET_INV_MATCH = (1 << IPSET_DIM_ZERO), - IPSET_DIM_ONE_SRC = (1 << IPSET_DIM_ONE), - IPSET_DIM_TWO_SRC = (1 << IPSET_DIM_TWO), - IPSET_DIM_THREE_SRC = (1 << IPSET_DIM_THREE), -}; - -#endif /* __IP_SET_H */ diff --git a/extensions/ipset-6/include/libipset/linux_ip_set_bitmap.h b/extensions/ipset-6/include/libipset/linux_ip_set_bitmap.h deleted file mode 100644 index 95fb963..0000000 --- a/extensions/ipset-6/include/libipset/linux_ip_set_bitmap.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __IP_SET_BITMAP_H -#define __IP_SET_BITMAP_H - -/* Bitmap type specific error codes */ -enum { - /* The element is out of the range of the set */ - IPSET_ERR_BITMAP_RANGE = IPSET_ERR_TYPE_SPECIFIC, - /* The range exceeds the size limit of the set type */ - IPSET_ERR_BITMAP_RANGE_SIZE, -}; - -#endif /* __IP_SET_BITMAP_H */ diff --git a/extensions/ipset-6/include/libipset/linux_ip_set_hash.h b/extensions/ipset-6/include/libipset/linux_ip_set_hash.h deleted file mode 100644 index 7a9e5f7..0000000 --- a/extensions/ipset-6/include/libipset/linux_ip_set_hash.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __IP_SET_HASH_H -#define __IP_SET_HASH_H - -/* Hash type specific error codes */ -enum { - /* Hash is full */ - IPSET_ERR_HASH_FULL = IPSET_ERR_TYPE_SPECIFIC, - /* Null-valued element */ - IPSET_ERR_HASH_ELEM, - /* Invalid protocol */ - IPSET_ERR_INVALID_PROTO, - /* Protocol missing but must be specified */ - IPSET_ERR_MISSING_PROTO, - /* Range not supported */ - IPSET_ERR_HASH_RANGE_UNSUPPORTED, - /* Invalid range */ - IPSET_ERR_HASH_RANGE, -}; - -#endif /* __IP_SET_HASH_H */ diff --git a/extensions/ipset-6/include/libipset/linux_ip_set_list.h b/extensions/ipset-6/include/libipset/linux_ip_set_list.h deleted file mode 100644 index 2395aa2..0000000 --- a/extensions/ipset-6/include/libipset/linux_ip_set_list.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __IP_SET_LIST_H -#define __IP_SET_LIST_H - -/* List type specific error codes */ -enum { - /* Set name to be added/deleted/tested does not exist. */ - IPSET_ERR_NAME = IPSET_ERR_TYPE_SPECIFIC, - /* list:set type is not permitted to add */ - IPSET_ERR_LOOP, - /* Missing reference set */ - IPSET_ERR_BEFORE, - /* Reference set does not exist */ - IPSET_ERR_NAMEREF, - /* Set is full */ - IPSET_ERR_LIST_FULL, - /* Reference set is not added to the set */ - IPSET_ERR_REF_EXIST, -}; - -#endif /* __IP_SET_LIST_H */ diff --git a/extensions/ipset-6/include/libipset/mnl.h b/extensions/ipset-6/include/libipset/mnl.h deleted file mode 100644 index 0516ec7..0000000 --- a/extensions/ipset-6/include/libipset/mnl.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_MNL_H -#define LIBIPSET_MNL_H - -#include /* uintxx_t */ -#include /* libmnl backend */ - -#include /* struct ipset_transport */ - -#ifndef NFNETLINK_V0 -#define NFNETLINK_V0 0 - -struct nfgenmsg { - uint8_t nfgen_family; - uint8_t version; - uint16_t res_id; -}; -#endif - -extern int ipset_get_nlmsg_type(const struct nlmsghdr *nlh); - -extern const struct ipset_transport ipset_mnl_transport; - -#endif /* LIBIPSET_MNL_H */ diff --git a/extensions/ipset-6/include/libipset/nf_inet_addr.h b/extensions/ipset-6/include/libipset/nf_inet_addr.h deleted file mode 100644 index 6c94e15..0000000 --- a/extensions/ipset-6/include/libipset/nf_inet_addr.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_NF_INET_ADDR_H -#define LIBIPSET_NF_INET_ADDR_H - -#include /* uint32_t */ -#include /* struct in[6]_addr */ - -/* The structure to hold IP addresses, same as in linux/netfilter.h */ -union nf_inet_addr { - uint32_t all[4]; - uint32_t ip; - uint32_t ip6[4]; - struct in_addr in; - struct in6_addr in6; -}; - -#endif /* LIBIPSET_NF_INET_ADDR_H */ diff --git a/extensions/ipset-6/include/libipset/nfproto.h b/extensions/ipset-6/include/libipset/nfproto.h deleted file mode 100644 index 800da11..0000000 --- a/extensions/ipset-6/include/libipset/nfproto.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LIBIPSET_NFPROTO_H -#define LIBIPSET_NFPROTO_H - -/* - * The constants to select, same as in linux/netfilter.h. - * Like nf_inet_addr.h, this is just here so that we need not to rely on - * the presence of a recent-enough netfilter.h. - */ -enum { - NFPROTO_UNSPEC = 0, - NFPROTO_IPV4 = 2, - NFPROTO_ARP = 3, - NFPROTO_BRIDGE = 7, - NFPROTO_IPV6 = 10, - NFPROTO_DECNET = 12, - NFPROTO_NUMPROTO, -}; - -#endif /* LIBIPSET_NFPROTO_H */ diff --git a/extensions/ipset-6/include/libipset/parse.h b/extensions/ipset-6/include/libipset/parse.h deleted file mode 100644 index 9f64a70..0000000 --- a/extensions/ipset-6/include/libipset/parse.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_PARSE_H -#define LIBIPSET_PARSE_H - -#include /* enum ipset_opt */ - -/* For parsing/printing data */ -#define IPSET_CIDR_SEPARATOR "/" -#define IPSET_RANGE_SEPARATOR "-" -#define IPSET_ELEM_SEPARATOR "," -#define IPSET_NAME_SEPARATOR "," -#define IPSET_PROTO_SEPARATOR ":" - -struct ipset_session; -struct ipset_arg; - -typedef int (*ipset_parsefn)(struct ipset_session *s, - enum ipset_opt opt, const char *str); - -extern int ipset_parse_ether(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_port(struct ipset_session *session, - enum ipset_opt opt, const char *str, - const char *proto); -extern int ipset_parse_tcpudp_port(struct ipset_session *session, - enum ipset_opt opt, const char *str, - const char *proto); -extern int ipset_parse_tcp_port(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_single_tcp_port(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_proto(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_icmp(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_icmpv6(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_proto_port(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_family(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_ip(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_single_ip(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_net(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_range(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_netrange(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_iprange(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_ipnet(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_ip4_single6(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_ip4_net6(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_name(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_before(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_after(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_setname(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_uint32(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_uint8(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_netmask(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_flag(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_typename(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_iface(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_output(struct ipset_session *session, - int opt, const char *str); -extern int ipset_parse_ignored(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_elem(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_call_parser(struct ipset_session *session, - const struct ipset_arg *arg, - const char *str); - -/* Compatibility parser functions */ -extern int ipset_parse_iptimeout(struct ipset_session *session, - enum ipset_opt opt, const char *str); -extern int ipset_parse_name_compat(struct ipset_session *session, - enum ipset_opt opt, const char *str); - -#endif /* LIBIPSET_PARSE_H */ diff --git a/extensions/ipset-6/include/libipset/pfxlen.h b/extensions/ipset-6/include/libipset/pfxlen.h deleted file mode 100644 index 58b4b4f..0000000 --- a/extensions/ipset-6/include/libipset/pfxlen.h +++ /dev/null @@ -1,157 +0,0 @@ -#ifndef _NET_PFXLEN_H -#define _NET_PFXLEN_H 1 - -#include -#ifdef HAVE_PFXLEN_H -#include -#else - -#include /* union nf_inet_addr */ - -#define E(a, b, c, d) \ - {.ip6 = { \ - __constant_htonl(a), __constant_htonl(b), \ - __constant_htonl(c), __constant_htonl(d), \ - } } - -/* - * This table works for both IPv4 and IPv6; - * just use prefixlen_netmask_map[prefixlength].ip. - */ -const union nf_inet_addr prefixlen_netmask_map[] = { - E(0x00000000, 0x00000000, 0x00000000, 0x00000000), - E(0x80000000, 0x00000000, 0x00000000, 0x00000000), - E(0xC0000000, 0x00000000, 0x00000000, 0x00000000), - E(0xE0000000, 0x00000000, 0x00000000, 0x00000000), - E(0xF0000000, 0x00000000, 0x00000000, 0x00000000), - E(0xF8000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFC000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFE000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFF000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFF800000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFC00000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFE00000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFF00000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFF80000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFC0000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFE0000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFF0000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFF8000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFC000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFE000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFF000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFF800, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFC00, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFE00, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFF00, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFF80, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFC0, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFE0, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFF0, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFF8, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFC, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFE, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0x80000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xC0000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xE0000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xF0000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xF8000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFC000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFE000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFF800000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFC00000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFE00000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFF00000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFF80000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFC0000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFE0000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFF0000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFF8000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFC000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFE000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFF000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFF800, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFC00, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFE00, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFF00, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFF80, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFC0, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFE0, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFF0, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFF8, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFC, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFE, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0x80000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xC0000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xE0000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xF0000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xF8000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFC000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFE000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFF800000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFC00000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFE00000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFF00000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFF80000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFC0000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFE0000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF8000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFC000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF800, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFC00, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFE00, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF80, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFC0, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFE0, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF0, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF8, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFC, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xC0000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xE0000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF0000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF8000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFC000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFE000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF800000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFC00000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFE00000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFF00000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFF80000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFC0000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFE0000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF8000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFC000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF800), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFC00), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFE00), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF80), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFC0), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFE0), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF0), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF8), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFC), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF), -}; -#endif /* !HAVE_PFXLEN_H */ - -#define PFXLEN(n) prefixlen_netmask_map[n].ip -#define PFXLEN6(n) prefixlen_netmask_map[n].ip6 - -#endif diff --git a/extensions/ipset-6/include/libipset/print.h b/extensions/ipset-6/include/libipset/print.h deleted file mode 100644 index 1d537bd..0000000 --- a/extensions/ipset-6/include/libipset/print.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_PRINT_H -#define LIBIPSET_PRINT_H - -#include /* enum ipset_opt */ - -typedef int (*ipset_printfn)(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); - -extern int ipset_print_ether(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_family(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_type(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_ip(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_ipaddr(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_number(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_name(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_port(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_iface(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_proto(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_icmp(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_icmpv6(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_proto_port(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_flag(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); -extern int ipset_print_elem(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); - -#define ipset_print_portnum ipset_print_number - -extern int ipset_print_data(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt, uint8_t env); - -#endif /* LIBIPSET_PRINT_H */ diff --git a/extensions/ipset-6/include/libipset/session.h b/extensions/ipset-6/include/libipset/session.h deleted file mode 100644 index 467bb2f..0000000 --- a/extensions/ipset-6/include/libipset/session.h +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_SESSION_H -#define LIBIPSET_SESSION_H - -#include /* bool */ -#include /* uintxx_t */ -#include /* printf */ - -#include /* enum ipset_cmd */ - -/* Report and output buffer sizes */ -#define IPSET_ERRORBUFLEN 1024 -#define IPSET_OUTBUFLEN 8192 - -struct ipset_session; -struct ipset_data; -struct ipset_handle; - -extern struct ipset_data * - ipset_session_data(const struct ipset_session *session); -extern struct ipset_handle * - ipset_session_handle(const struct ipset_session *session); -extern const struct ipset_type * - ipset_saved_type(const struct ipset_session *session); -extern void ipset_session_lineno(struct ipset_session *session, - uint32_t lineno); - -enum ipset_err_type { - IPSET_ERROR, - IPSET_WARNING, -}; - -extern int ipset_session_report(struct ipset_session *session, - enum ipset_err_type type, - const char *fmt, ...); - -#define ipset_err(session, fmt, args...) \ - ipset_session_report(session, IPSET_ERROR, fmt , ## args) - -#define ipset_warn(session, fmt, args...) \ - ipset_session_report(session, IPSET_WARNING, fmt , ## args) - -#define ipset_errptr(session, fmt, args...) ({ \ - ipset_session_report(session, IPSET_ERROR, fmt , ## args); \ - NULL; \ -}) - -extern void ipset_session_report_reset(struct ipset_session *session); -extern const char *ipset_session_error(const struct ipset_session *session); -extern const char *ipset_session_warning(const struct ipset_session *session); - -#define ipset_session_data_set(session, opt, value) \ - ipset_data_set(ipset_session_data(session), opt, value) -#define ipset_session_data_get(session, opt) \ - ipset_data_get(ipset_session_data(session), opt) - -/* Environment option flags */ -enum ipset_envopt { - IPSET_ENV_BIT_SORTED = 0, - IPSET_ENV_SORTED = (1 << IPSET_ENV_BIT_SORTED), - IPSET_ENV_BIT_QUIET = 1, - IPSET_ENV_QUIET = (1 << IPSET_ENV_BIT_QUIET), - IPSET_ENV_BIT_RESOLVE = 2, - IPSET_ENV_RESOLVE = (1 << IPSET_ENV_BIT_RESOLVE), - IPSET_ENV_BIT_EXIST = 3, - IPSET_ENV_EXIST = (1 << IPSET_ENV_BIT_EXIST), - IPSET_ENV_BIT_LIST_SETNAME = 4, - IPSET_ENV_LIST_SETNAME = (1 << IPSET_ENV_BIT_LIST_SETNAME), - IPSET_ENV_BIT_LIST_HEADER = 5, - IPSET_ENV_LIST_HEADER = (1 << IPSET_ENV_BIT_LIST_HEADER), -}; - -extern int ipset_envopt_parse(struct ipset_session *session, - int env, const char *str); -extern bool ipset_envopt_test(struct ipset_session *session, - enum ipset_envopt env); - -enum ipset_output_mode { - IPSET_LIST_NONE, - IPSET_LIST_PLAIN, - IPSET_LIST_SAVE, - IPSET_LIST_XML, -}; - -extern int ipset_session_output(struct ipset_session *session, - enum ipset_output_mode mode); - -extern int ipset_commit(struct ipset_session *session); -extern int ipset_cmd(struct ipset_session *session, enum ipset_cmd cmd, - uint32_t lineno); - -typedef int (*ipset_outfn)(const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); - -extern struct ipset_session *ipset_session_init(ipset_outfn outfn); -extern int ipset_session_fini(struct ipset_session *session); - -extern void ipset_debug_msg(const char *dir, void *buffer, int len); - -#endif /* LIBIPSET_SESSION_H */ diff --git a/extensions/ipset-6/include/libipset/transport.h b/extensions/ipset-6/include/libipset/transport.h deleted file mode 100644 index a9209cd..0000000 --- a/extensions/ipset-6/include/libipset/transport.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_TRANSPORT_H -#define LIBIPSET_TRANSPORT_H - -#include /* uintxx_t */ -#include /* struct nlmsghdr */ - -#include /* mnl_cb_t */ - -#include /* enum ipset_cmd */ - -struct ipset_handle; - -struct ipset_transport { - struct ipset_handle * (*init)(mnl_cb_t *cb_ctl, void *data); - int (*fini)(struct ipset_handle *handle); - void (*fill_hdr)(struct ipset_handle *handle, enum ipset_cmd cmd, - void *buffer, size_t len, uint8_t envflags); - int (*query)(struct ipset_handle *handle, void *buffer, size_t len); -}; - -#endif /* LIBIPSET_TRANSPORT_H */ diff --git a/extensions/ipset-6/include/libipset/types.h b/extensions/ipset-6/include/libipset/types.h deleted file mode 100644 index cacce26..0000000 --- a/extensions/ipset-6/include/libipset/types.h +++ /dev/null @@ -1,109 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_TYPES_H -#define LIBIPSET_TYPES_H - -#include /* NULL */ -#include /* uintxx_t */ - -#include /* enum ipset_opt */ -#include /* ipset_parsefn */ -#include /* ipset_printfn */ -#include /* IPSET_MAXNAMELEN */ -#include /* for NFPROTO_ */ - -/* Family rules: - * - NFPROTO_UNSPEC: type is family-neutral - * - NFPROTO_IPV4: type supports IPv4 only - * - NFPROTO_IPV6: type supports IPv6 only - * Special (userspace) ipset-only extra value: - * - NFPROTO_IPSET_IPV46: type supports both IPv4 and IPv6 - */ -enum { - NFPROTO_IPSET_IPV46 = 255, -}; - -/* The maximal type dimension userspace supports */ -#define IPSET_DIM_UMAX 3 - -/* Parser options */ -enum { - IPSET_NO_ARG = -1, - IPSET_OPTIONAL_ARG, - IPSET_MANDATORY_ARG, - IPSET_MANDATORY_ARG2, -}; - -struct ipset_session; - -/* Parse and print type-specific arguments */ -struct ipset_arg { - const char *name[2]; /* option names */ - int has_arg; /* mandatory/optional/no arg */ - enum ipset_opt opt; /* argumentum type */ - ipset_parsefn parse; /* parser function */ - ipset_printfn print; /* printing function */ -}; - -/* Type check against the kernel */ -enum { - IPSET_KERNEL_MISMATCH = -1, - IPSET_KERNEL_CHECK_NEEDED, - IPSET_KERNEL_OK, -}; - -/* How element parts are parsed */ -struct ipset_elem { - ipset_parsefn parse; /* elem parser function */ - ipset_printfn print; /* elem print function */ - enum ipset_opt opt; /* elem option */ -}; - -/* The set types in userspace - * we could collapse 'args' and 'mandatory' to two-element lists - * but for the readability the full list is supported. - */ -struct ipset_type { - const char *name; - uint8_t revision; /* revision number */ - uint8_t family; /* supported family */ - uint8_t dimension; /* elem dimension */ - int8_t kernel_check; /* kernel check */ - bool last_elem_optional; /* last element optional */ - struct ipset_elem elem[IPSET_DIM_UMAX]; /* parse elem */ - ipset_parsefn compat_parse_elem; /* compatibility parser */ - const struct ipset_arg *args[IPSET_CADT_MAX]; /* create/ADT args besides elem */ - uint64_t mandatory[IPSET_CADT_MAX]; /* create/ADT mandatory flags */ - uint64_t full[IPSET_CADT_MAX]; /* full args flags */ - const char *usage; /* terse usage */ - void (*usagefn)(void); /* additional usage */ - - struct ipset_type *next; - const char *alias[]; /* name alias(es) */ -}; - -extern int ipset_cache_add(const char *name, const struct ipset_type *type, - uint8_t family); -extern int ipset_cache_del(const char *name); -extern int ipset_cache_rename(const char *from, const char *to); -extern int ipset_cache_swap(const char *from, const char *to); - -extern int ipset_cache_init(void); -extern void ipset_cache_fini(void); - -extern const struct ipset_type * - ipset_type_get(struct ipset_session *session, enum ipset_cmd cmd); -extern const struct ipset_type * - ipset_type_check(struct ipset_session *session); - -extern int ipset_type_add(struct ipset_type *type); -extern const struct ipset_type *ipset_types(void); -extern const char *ipset_typename_resolve(const char *str); -extern bool ipset_match_typename(const char *str, - const struct ipset_type *t); - -#endif /* LIBIPSET_TYPES_H */ diff --git a/extensions/ipset-6/include/libipset/ui.h b/extensions/ipset-6/include/libipset/ui.h deleted file mode 100644 index 4c9a163..0000000 --- a/extensions/ipset-6/include/libipset/ui.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_UI_H -#define LIBIPSET_UI_H - -#include /* enum ipset_cmd */ - -/* Commands in userspace */ -struct ipset_commands { - enum ipset_cmd cmd; - int has_arg; - const char *name[2]; - const char *help; -}; - -extern const struct ipset_commands ipset_commands[]; - -struct ipset_session; -struct ipset_data; - -/* Environment options */ -struct ipset_envopts { - int flag; - int has_arg; - const char *name[2]; - const char *help; - int (*parse)(struct ipset_session *s, int flag, const char *str); - int (*print)(char *buf, unsigned int len, - const struct ipset_data *data, int flag, uint8_t env); -}; - -extern const struct ipset_envopts ipset_envopts[]; - -extern bool ipset_match_cmd(const char *arg, const char * const name[]); -extern bool ipset_match_option(const char *arg, const char * const name[]); -extern bool ipset_match_envopt(const char *arg, const char * const name[]); -extern void ipset_shift_argv(int *argc, char *argv[], int from); -extern void ipset_port_usage(void); - -#endif /* LIBIPSET_UI_H */ diff --git a/extensions/ipset-6/include/libipset/utils.h b/extensions/ipset-6/include/libipset/utils.h deleted file mode 100644 index df5b59e..0000000 --- a/extensions/ipset-6/include/libipset/utils.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef LIBIPSET_UTILS_H -#define LIBIPSET_UTILS_H - -#include /* strcmp */ -#include /* struct in[6]_addr */ - -/* String equality tests */ -#define STREQ(a, b) (strcmp(a, b) == 0) -#define STRNEQ(a, b, n) (strncmp(a, b, n) == 0) -#define STRCASEQ(a, b) (strcasecmp(a, b) == 0) -#define STRNCASEQ(a, b, n) (strncasecmp(a, b, n) == 0) - -/* Stringify tokens */ -#define _STR(c) #c -#define STR(c) _STR(c) - -/* Min/max */ -#define MIN(a, b) (a < b ? a : b) -#define MAX(a, b) (a > b ? a : b) - -#define UNUSED __attribute__ ((unused)) -#ifdef NDEBUG -#define ASSERT_UNUSED UNUSED -#else -#define ASSERT_UNUSED -#endif - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) -#endif - -static inline void -in4cpy(struct in_addr *dest, const struct in_addr *src) -{ - dest->s_addr = src->s_addr; -} - -static inline void -in6cpy(struct in6_addr *dest, const struct in6_addr *src) -{ - memcpy(dest, src, sizeof(struct in6_addr)); -} - -#endif /* LIBIPSET_UTILS_H */ diff --git a/extensions/ipset-6/ip_set.h b/extensions/ipset-6/ip_set.h deleted file mode 100644 index 52c1cd1..0000000 --- a/extensions/ipset-6/ip_set.h +++ /dev/null @@ -1,499 +0,0 @@ -#ifndef _IP_SET_H -#define _IP_SET_H - -/* Copyright (C) 2000-2002 Joakim Axelsson - * Patrick Schaaf - * Martin Josefsson - * Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include - -/* The protocol version */ -#define IPSET_PROTOCOL 0x60 - -/* The max length of strings including NUL: set and type identifiers */ -#define IPSET_MAXNAMELEN 32 - -/* Message types and commands */ -enum ipset_cmd { - IPSET_CMD_NONE, - IPSET_CMD_PROTOCOL, /* 1: Return protocol version */ - IPSET_CMD_CREATE, /* 2: Create a new (empty) set */ - IPSET_CMD_DESTROY, /* 3: Destroy a (empty) set */ - IPSET_CMD_FLUSH, /* 4: Remove all elements from a set */ - IPSET_CMD_RENAME, /* 5: Rename a set */ - IPSET_CMD_SWAP, /* 6: Swap two sets */ - IPSET_CMD_LIST, /* 7: List sets */ - IPSET_CMD_SAVE, /* 8: Save sets */ - IPSET_CMD_ADD, /* 9: Add an element to a set */ - IPSET_CMD_DEL, /* 10: Delete an element from a set */ - IPSET_CMD_TEST, /* 11: Test an element in a set */ - IPSET_CMD_HEADER, /* 12: Get set header data only */ - IPSET_CMD_TYPE, /* 13: Get set type */ - IPSET_MSG_MAX, /* Netlink message commands */ - - /* Commands in userspace: */ - IPSET_CMD_RESTORE = IPSET_MSG_MAX, /* 14: Enter restore mode */ - IPSET_CMD_HELP, /* 15: Get help */ - IPSET_CMD_VERSION, /* 16: Get program version */ - IPSET_CMD_QUIT, /* 17: Quit from interactive mode */ - - IPSET_CMD_MAX, - - IPSET_CMD_COMMIT = IPSET_CMD_MAX, /* 18: Commit buffered commands */ -}; - -/* Attributes at command level */ -enum { - IPSET_ATTR_UNSPEC, - IPSET_ATTR_PROTOCOL, /* 1: Protocol version */ - IPSET_ATTR_SETNAME, /* 2: Name of the set */ - IPSET_ATTR_TYPENAME, /* 3: Typename */ - IPSET_ATTR_SETNAME2 = IPSET_ATTR_TYPENAME, /* Setname at rename/swap */ - IPSET_ATTR_REVISION, /* 4: Settype revision */ - IPSET_ATTR_FAMILY, /* 5: Settype family */ - IPSET_ATTR_FLAGS, /* 6: Flags at command level */ - IPSET_ATTR_DATA, /* 7: Nested attributes */ - IPSET_ATTR_ADT, /* 8: Multiple data containers */ - IPSET_ATTR_LINENO, /* 9: Restore lineno */ - IPSET_ATTR_PROTOCOL_MIN, /* 10: Minimal supported version number */ - IPSET_ATTR_REVISION_MIN = IPSET_ATTR_PROTOCOL_MIN, /* type rev min */ - __IPSET_ATTR_CMD_MAX, -}; -#define IPSET_ATTR_CMD_MAX (__IPSET_ATTR_CMD_MAX - 1) - -/* CADT specific attributes */ -enum { - IPSET_ATTR_IP = IPSET_ATTR_UNSPEC + 1, - IPSET_ATTR_IP_FROM = IPSET_ATTR_IP, - IPSET_ATTR_IP_TO, /* 2 */ - IPSET_ATTR_CIDR, /* 3 */ - IPSET_ATTR_PORT, /* 4 */ - IPSET_ATTR_PORT_FROM = IPSET_ATTR_PORT, - IPSET_ATTR_PORT_TO, /* 5 */ - IPSET_ATTR_TIMEOUT, /* 6 */ - IPSET_ATTR_PROTO, /* 7 */ - IPSET_ATTR_CADT_FLAGS, /* 8 */ - IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO, /* 9 */ - /* Reserve empty slots */ - IPSET_ATTR_CADT_MAX = 16, - /* Create-only specific attributes */ - IPSET_ATTR_GC, - IPSET_ATTR_HASHSIZE, - IPSET_ATTR_MAXELEM, - IPSET_ATTR_NETMASK, - IPSET_ATTR_PROBES, - IPSET_ATTR_RESIZE, - IPSET_ATTR_SIZE, - /* Kernel-only */ - IPSET_ATTR_ELEMENTS, - IPSET_ATTR_REFERENCES, - IPSET_ATTR_MEMSIZE, - - __IPSET_ATTR_CREATE_MAX, -}; -#define IPSET_ATTR_CREATE_MAX (__IPSET_ATTR_CREATE_MAX - 1) - -/* ADT specific attributes */ -enum { - IPSET_ATTR_ETHER = IPSET_ATTR_CADT_MAX + 1, - IPSET_ATTR_NAME, - IPSET_ATTR_NAMEREF, - IPSET_ATTR_IP2, - IPSET_ATTR_CIDR2, - IPSET_ATTR_IP2_TO, - IPSET_ATTR_IFACE, - __IPSET_ATTR_ADT_MAX, -}; -#define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1) - -/* IP specific attributes */ -enum { - IPSET_ATTR_IPADDR_IPV4 = IPSET_ATTR_UNSPEC + 1, - IPSET_ATTR_IPADDR_IPV6, - __IPSET_ATTR_IPADDR_MAX, -}; -#define IPSET_ATTR_IPADDR_MAX (__IPSET_ATTR_IPADDR_MAX - 1) - -/* Error codes */ -enum ipset_errno { - IPSET_ERR_PRIVATE = 4096, - IPSET_ERR_PROTOCOL, - IPSET_ERR_FIND_TYPE, - IPSET_ERR_MAX_SETS, - IPSET_ERR_BUSY, - IPSET_ERR_EXIST_SETNAME2, - IPSET_ERR_TYPE_MISMATCH, - IPSET_ERR_EXIST, - IPSET_ERR_INVALID_CIDR, - IPSET_ERR_INVALID_NETMASK, - IPSET_ERR_INVALID_FAMILY, - IPSET_ERR_TIMEOUT, - IPSET_ERR_REFERENCED, - IPSET_ERR_IPADDR_IPV4, - IPSET_ERR_IPADDR_IPV6, - - /* Type specific error codes */ - IPSET_ERR_TYPE_SPECIFIC = 4352, -}; - -/* Flags at command level */ -enum ipset_cmd_flags { - IPSET_FLAG_BIT_EXIST = 0, - IPSET_FLAG_EXIST = (1 << IPSET_FLAG_BIT_EXIST), - IPSET_FLAG_BIT_LIST_SETNAME = 1, - IPSET_FLAG_LIST_SETNAME = (1 << IPSET_FLAG_BIT_LIST_SETNAME), - IPSET_FLAG_BIT_LIST_HEADER = 2, - IPSET_FLAG_LIST_HEADER = (1 << IPSET_FLAG_BIT_LIST_HEADER), -}; - -/* Flags at CADT attribute level */ -enum ipset_cadt_flags { - IPSET_FLAG_BIT_BEFORE = 0, - IPSET_FLAG_BEFORE = (1 << IPSET_FLAG_BIT_BEFORE), - IPSET_FLAG_BIT_PHYSDEV = 1, - IPSET_FLAG_PHYSDEV = (1 << IPSET_FLAG_BIT_PHYSDEV), -}; - -/* Commands with settype-specific attributes */ -enum ipset_adt { - IPSET_ADD, - IPSET_DEL, - IPSET_TEST, - IPSET_ADT_MAX, - IPSET_CREATE = IPSET_ADT_MAX, - IPSET_CADT_MAX, -}; - -/* Sets are identified by an index in kernel space. Tweak with ip_set_id_t - * and IPSET_INVALID_ID if you want to increase the max number of sets. - */ -typedef __u16 ip_set_id_t; - -#define IPSET_INVALID_ID 65535 - -enum ip_set_dim { - IPSET_DIM_ZERO = 0, - IPSET_DIM_ONE, - IPSET_DIM_TWO, - IPSET_DIM_THREE, - /* Max dimension in elements. - * If changed, new revision of iptables match/target is required. - */ - IPSET_DIM_MAX = 6, -}; - -/* Option flags for kernel operations */ -enum ip_set_kopt { - IPSET_INV_MATCH = (1 << IPSET_DIM_ZERO), - IPSET_DIM_ONE_SRC = (1 << IPSET_DIM_ONE), - IPSET_DIM_TWO_SRC = (1 << IPSET_DIM_TWO), - IPSET_DIM_THREE_SRC = (1 << IPSET_DIM_THREE), -}; - -#ifdef __KERNEL__ -#include -#include -#include -#include -#include -#include -#include - -/* Set features */ -enum ip_set_feature { - IPSET_TYPE_IP_FLAG = 0, - IPSET_TYPE_IP = (1 << IPSET_TYPE_IP_FLAG), - IPSET_TYPE_PORT_FLAG = 1, - IPSET_TYPE_PORT = (1 << IPSET_TYPE_PORT_FLAG), - IPSET_TYPE_MAC_FLAG = 2, - IPSET_TYPE_MAC = (1 << IPSET_TYPE_MAC_FLAG), - IPSET_TYPE_IP2_FLAG = 3, - IPSET_TYPE_IP2 = (1 << IPSET_TYPE_IP2_FLAG), - IPSET_TYPE_NAME_FLAG = 4, - IPSET_TYPE_NAME = (1 << IPSET_TYPE_NAME_FLAG), - IPSET_TYPE_IFACE_FLAG = 5, - IPSET_TYPE_IFACE = (1 << IPSET_TYPE_IFACE_FLAG), - /* Strictly speaking not a feature, but a flag for dumping: - * this settype must be dumped last */ - IPSET_DUMP_LAST_FLAG = 7, - IPSET_DUMP_LAST = (1 << IPSET_DUMP_LAST_FLAG), -}; - -struct ip_set; - -typedef int (*ipset_adtfn)(struct ip_set *set, void *value, - u32 timeout, u32 flags); - -/* Kernel API function options */ -struct ip_set_adt_opt { - u8 family; /* Actual protocol family */ - u8 dim; /* Dimension of match/target */ - u8 flags; /* Direction and negation flags */ - u32 cmdflags; /* Command-like flags */ - u32 timeout; /* Timeout value */ -}; - -/* Set type, variant-specific part */ -struct ip_set_type_variant { - /* Kernelspace: test/add/del entries - * returns negative error code, - * zero for no match/success to add/delete - * positive for matching element */ - int (*kadt)(struct ip_set *set, const struct sk_buff * skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt); - - /* Userspace: test/add/del entries - * returns negative error code, - * zero for no match/success to add/delete - * positive for matching element */ - int (*uadt)(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried); - - /* Low level add/del/test functions */ - ipset_adtfn adt[IPSET_ADT_MAX]; - - /* When adding entries and set is full, try to resize the set */ - int (*resize)(struct ip_set *set, bool retried); - /* Destroy the set */ - void (*destroy)(struct ip_set *set); - /* Flush the elements */ - void (*flush)(struct ip_set *set); - /* Expire entries before listing */ - void (*expire)(struct ip_set *set); - /* List set header data */ - int (*head)(struct ip_set *set, struct sk_buff *skb); - /* List elements */ - int (*list)(const struct ip_set *set, struct sk_buff *skb, - struct netlink_callback *cb); - - /* Return true if "b" set is the same as "a" - * according to the create set parameters */ - bool (*same_set)(const struct ip_set *a, const struct ip_set *b); -}; - -/* The core set type structure */ -struct ip_set_type { - struct list_head list; - - /* Typename */ - char name[IPSET_MAXNAMELEN]; - /* Protocol version */ - u8 protocol; - /* Set features to control swapping */ - u8 features; - /* Set type dimension */ - u8 dimension; - /* - * Supported family: may be NFPROTO_UNSPEC for both - * NFPROTO_IPV4/NFPROTO_IPV6. - */ - u8 family; - /* Type revisions */ - u8 revision_min, revision_max; - - /* Create set */ - int (*create)(struct ip_set *set, struct nlattr *tb[], u32 flags); - - /* Attribute policies */ - const struct nla_policy create_policy[IPSET_ATTR_CREATE_MAX + 1]; - const struct nla_policy adt_policy[IPSET_ATTR_ADT_MAX + 1]; - - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ - struct module *me; -}; - -/* register and unregister set type */ -extern int ip_set_type_register(struct ip_set_type *set_type); -extern void ip_set_type_unregister(struct ip_set_type *set_type); - -/* A generic IP set */ -struct ip_set { - /* The name of the set */ - char name[IPSET_MAXNAMELEN]; - /* Lock protecting the set data */ - rwlock_t lock; - /* References to the set */ - u32 ref; - /* The core set type */ - struct ip_set_type *type; - /* The type variant doing the real job */ - const struct ip_set_type_variant *variant; - /* The actual INET family of the set */ - u8 family; - /* The type revision */ - u8 revision; - /* The type specific data */ - void *data; -}; - -/* register and unregister set references */ -extern ip_set_id_t ip_set_get_byname(const char *name, struct ip_set **set); -extern void ip_set_put_byindex(ip_set_id_t index); -extern const char *ip_set_name_byindex(ip_set_id_t index); -extern ip_set_id_t ip_set_nfnl_get(const char *name); -extern ip_set_id_t ip_set_nfnl_get_byindex(ip_set_id_t index); -extern void ip_set_nfnl_put(ip_set_id_t index); - -/* API for iptables set match, and SET target */ - -extern int ip_set_add(ip_set_id_t id, const struct sk_buff *skb, - const struct xt_action_param *par, - const struct ip_set_adt_opt *opt); -extern int ip_set_del(ip_set_id_t id, const struct sk_buff *skb, - const struct xt_action_param *par, - const struct ip_set_adt_opt *opt); -extern int ip_set_test(ip_set_id_t id, const struct sk_buff *skb, - const struct xt_action_param *par, - const struct ip_set_adt_opt *opt); - -/* Utility functions */ -extern void *ip_set_alloc(size_t size); -extern void ip_set_free(void *members); -extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr); -extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr); - -static inline int -ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr) -{ - __be32 ip; - int ret = ip_set_get_ipaddr4(nla, &ip); - - if (ret) - return ret; - *ipaddr = ntohl(ip); - return 0; -} - -/* Ignore IPSET_ERR_EXIST errors if asked to do so? */ -static inline bool -ip_set_eexist(int ret, u32 flags) -{ - return ret == -IPSET_ERR_EXIST && (flags & IPSET_FLAG_EXIST); -} - -/* Check the NLA_F_NET_BYTEORDER flag */ -static inline bool -ip_set_attr_netorder(struct nlattr *tb[], int type) -{ - return tb[type] && (tb[type]->nla_type & NLA_F_NET_BYTEORDER); -} - -static inline bool -ip_set_optattr_netorder(struct nlattr *tb[], int type) -{ - return !tb[type] || (tb[type]->nla_type & NLA_F_NET_BYTEORDER); -} - -/* Useful converters */ -static inline u32 -ip_set_get_h32(const struct nlattr *attr) -{ - return ntohl(nla_get_be32(attr)); -} - -static inline u16 -ip_set_get_h16(const struct nlattr *attr) -{ - return ntohs(nla_get_be16(attr)); -} - -#define ipset_nest_start(skb, attr) nla_nest_start(skb, attr | NLA_F_NESTED) -#define ipset_nest_end(skb, start) nla_nest_end(skb, start) - -#ifndef NLA_PUT_NET16 -#define NLA_PUT_NET16(skb, attrtype, value) \ - NLA_PUT_BE16(skb, attrtype | NLA_F_NET_BYTEORDER, value) -#endif -#ifndef NLA_PUT_NET32 -#define NLA_PUT_NET32(skb, attrtype, value) \ - NLA_PUT_BE32(skb, attrtype | NLA_F_NET_BYTEORDER, value) -#endif -#ifndef NLA_PUT_NET64 -#define NLA_PUT_NET64(skb, attrtype, value) \ - NLA_PUT_BE64(skb, attrtype | NLA_F_NET_BYTEORDER, value) -#endif - -#define NLA_PUT_IPADDR4(skb, type, ipaddr) \ -do { \ - struct nlattr *__nested = ipset_nest_start(skb, type); \ - \ - if (!__nested) \ - goto nla_put_failure; \ - NLA_PUT_NET32(skb, IPSET_ATTR_IPADDR_IPV4, ipaddr); \ - ipset_nest_end(skb, __nested); \ -} while (0) - -#define NLA_PUT_IPADDR6(skb, type, ipaddrptr) \ -do { \ - struct nlattr *__nested = ipset_nest_start(skb, type); \ - \ - if (!__nested) \ - goto nla_put_failure; \ - NLA_PUT(skb, IPSET_ATTR_IPADDR_IPV6, \ - sizeof(struct in6_addr), ipaddrptr); \ - ipset_nest_end(skb, __nested); \ -} while (0) - -/* Get address from skbuff */ -static inline __be32 -ip4addr(const struct sk_buff *skb, bool src) -{ - return src ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr; -} - -static inline void -ip4addrptr(const struct sk_buff *skb, bool src, __be32 *addr) -{ - *addr = src ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr; -} - -static inline void -ip6addrptr(const struct sk_buff *skb, bool src, struct in6_addr *addr) -{ - memcpy(addr, src ? &ipv6_hdr(skb)->saddr : &ipv6_hdr(skb)->daddr, - sizeof(*addr)); -} - -/* Calculate the bytes required to store the inclusive range of a-b */ -static inline int -bitmap_bytes(u32 a, u32 b) -{ - return 4 * ((((b - a + 8) / 8) + 3) / 4); -} - -#endif /* __KERNEL__ */ - -/* Interface to iptables/ip6tables */ - -#define SO_IP_SET 83 - -union ip_set_name_index { - char name[IPSET_MAXNAMELEN]; - ip_set_id_t index; -}; - -#define IP_SET_OP_GET_BYNAME 0x00000006 /* Get set index by name */ -struct ip_set_req_get_set { - unsigned op; - unsigned version; - union ip_set_name_index set; -}; - -#define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */ -/* Uses ip_set_req_get_set */ - -#define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */ -struct ip_set_req_version { - unsigned op; - unsigned version; -}; - -#endif /*_IP_SET_H */ diff --git a/extensions/ipset-6/ip_set_ahash.h b/extensions/ipset-6/ip_set_ahash.h deleted file mode 100644 index d37ba9a..0000000 --- a/extensions/ipset-6/ip_set_ahash.h +++ /dev/null @@ -1,1133 +0,0 @@ -#ifndef _IP_SET_AHASH_H -#define _IP_SET_AHASH_H - -#include -#include "jhash.h" -#include "ip_set_timeout.h" - -#define CONCAT(a, b, c) a##b##c -#define TOKEN(a, b, c) CONCAT(a, b, c) - -#define type_pf_next TOKEN(TYPE, PF, _elem) - -/* Hashing which uses arrays to resolve clashing. The hash table is resized - * (doubled) when searching becomes too long. - * Internally jhash is used with the assumption that the size of the - * stored data is a multiple of sizeof(u32). If storage supports timeout, - * the timeout field must be the last one in the data structure - that field - * is ignored when computing the hash key. - * - * Readers and resizing - * - * Resizing can be triggered by userspace command only, and those - * are serialized by the nfnl mutex. During resizing the set is - * read-locked, so the only possible concurrent operations are - * the kernel side readers. Those must be protected by proper RCU locking. - */ - -/* Number of elements to store in an initial array block */ -#define AHASH_INIT_SIZE 4 -/* Max number of elements to store in an array block */ -#define AHASH_MAX_SIZE (3*AHASH_INIT_SIZE) - -/* Max number of elements can be tuned */ -#ifdef IP_SET_HASH_WITH_MULTI -#define AHASH_MAX(h) ((h)->ahash_max) - -static inline u8 -tune_ahash_max(u8 curr, u32 multi) -{ - u32 n; - - if (multi < curr) - return curr; - - n = curr + AHASH_INIT_SIZE; - /* Currently, at listing one hash bucket must fit into a message. - * Therefore we have a hard limit here. - */ - return n > curr && n <= 64 ? n : curr; -} -#define TUNE_AHASH_MAX(h, multi) \ - ((h)->ahash_max = tune_ahash_max((h)->ahash_max, multi)) -#else -#define AHASH_MAX(h) AHASH_MAX_SIZE -#define TUNE_AHASH_MAX(h, multi) -#endif - -/* A hash bucket */ -struct hbucket { - void *value; /* the array of the values */ - u8 size; /* size of the array */ - u8 pos; /* position of the first free entry */ -}; - -/* The hash table: the table size stored here in order to make resizing easy */ -struct htable { - u8 htable_bits; /* size of hash table == 2^htable_bits */ - struct hbucket bucket[0]; /* hashtable buckets */ -}; - -#define hbucket(h, i) (&((h)->bucket[i])) - -/* Book-keeping of the prefixes added to the set */ -struct ip_set_hash_nets { - u8 cidr; /* the different cidr values in the set */ - u32 nets; /* number of elements per cidr */ -}; - -/* The generic ip_set hash structure */ -struct ip_set_hash { - struct htable *table; /* the hash table */ - u32 maxelem; /* max elements in the hash */ - u32 elements; /* current element (vs timeout) */ - u32 initval; /* random jhash init value */ - u32 timeout; /* timeout value, if enabled */ - struct timer_list gc; /* garbage collection when timeout enabled */ - struct type_pf_next next; /* temporary storage for uadd */ -#ifdef IP_SET_HASH_WITH_MULTI - u8 ahash_max; /* max elements in an array block */ -#endif -#ifdef IP_SET_HASH_WITH_NETMASK - u8 netmask; /* netmask value for subnets to store */ -#endif -#ifdef IP_SET_HASH_WITH_RBTREE - struct rb_root rbtree; -#endif -#ifdef IP_SET_HASH_WITH_NETS - struct ip_set_hash_nets nets[0]; /* book-keeping of prefixes */ -#endif -}; - -/* Compute htable_bits from the user input parameter hashsize */ -static u8 -htable_bits(u32 hashsize) -{ - /* Assume that hashsize == 2^htable_bits */ - u8 bits = fls(hashsize - 1); - if (jhash_size(bits) != hashsize) - /* Round up to the first 2^n value */ - bits = fls(hashsize); - - return bits; -} - -#ifdef IP_SET_HASH_WITH_NETS - -#define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128) - -/* Network cidr size book keeping when the hash stores different - * sized networks */ -static void -add_cidr(struct ip_set_hash *h, u8 cidr, u8 host_mask) -{ - u8 i; - - ++h->nets[cidr-1].nets; - - pr_debug("add_cidr added %u: %u\n", cidr, h->nets[cidr-1].nets); - - if (h->nets[cidr-1].nets > 1) - return; - - /* New cidr size */ - for (i = 0; i < host_mask && h->nets[i].cidr; i++) { - /* Add in increasing prefix order, so larger cidr first */ - if (h->nets[i].cidr < cidr) - swap(h->nets[i].cidr, cidr); - } - if (i < host_mask) - h->nets[i].cidr = cidr; -} - -static void -del_cidr(struct ip_set_hash *h, u8 cidr, u8 host_mask) -{ - u8 i; - - --h->nets[cidr-1].nets; - - pr_debug("del_cidr deleted %u: %u\n", cidr, h->nets[cidr-1].nets); - - if (h->nets[cidr-1].nets != 0) - return; - - /* All entries with this cidr size deleted, so cleanup h->cidr[] */ - for (i = 0; i < host_mask - 1 && h->nets[i].cidr; i++) { - if (h->nets[i].cidr == cidr) - h->nets[i].cidr = cidr = h->nets[i+1].cidr; - } - h->nets[i - 1].cidr = 0; -} -#endif - -/* Destroy the hashtable part of the set */ -static void -ahash_destroy(struct htable *t) -{ - struct hbucket *n; - u32 i; - - for (i = 0; i < jhash_size(t->htable_bits); i++) { - n = hbucket(t, i); - if (n->size) - /* FIXME: use slab cache */ - kfree(n->value); - } - - ip_set_free(t); -} - -/* Calculate the actual memory size of the set data */ -static size_t -ahash_memsize(const struct ip_set_hash *h, size_t dsize, u8 host_mask) -{ - u32 i; - struct htable *t = h->table; - size_t memsize = sizeof(*h) - + sizeof(*t) -#ifdef IP_SET_HASH_WITH_NETS - + sizeof(struct ip_set_hash_nets) * host_mask -#endif - + jhash_size(t->htable_bits) * sizeof(struct hbucket); - - for (i = 0; i < jhash_size(t->htable_bits); i++) - memsize += t->bucket[i].size * dsize; - - return memsize; -} - -/* Flush a hash type of set: destroy all elements */ -static void -ip_set_hash_flush(struct ip_set *set) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - struct hbucket *n; - u32 i; - - for (i = 0; i < jhash_size(t->htable_bits); i++) { - n = hbucket(t, i); - if (n->size) { - n->size = n->pos = 0; - /* FIXME: use slab cache */ - kfree(n->value); - } - } -#ifdef IP_SET_HASH_WITH_NETS - memset(h->nets, 0, sizeof(struct ip_set_hash_nets) - * SET_HOST_MASK(set->family)); -#endif - h->elements = 0; -} - -/* Destroy a hash type of set */ -static void -ip_set_hash_destroy(struct ip_set *set) -{ - struct ip_set_hash *h = set->data; - - if (with_timeout(h->timeout)) - del_timer_sync(&h->gc); - - ahash_destroy(h->table); -#ifdef IP_SET_HASH_WITH_RBTREE - rbtree_destroy(&h->rbtree); -#endif - kfree(h); - - set->data = NULL; -} - -#endif /* _IP_SET_AHASH_H */ - -#ifndef HKEY_DATALEN -#define HKEY_DATALEN sizeof(struct type_pf_elem) -#endif - -#define HKEY(data, initval, htable_bits) \ -(jhash2((u32 *)(data), HKEY_DATALEN/sizeof(u32), initval) \ - & jhash_mask(htable_bits)) - -#define CONCAT(a, b, c) a##b##c -#define TOKEN(a, b, c) CONCAT(a, b, c) - -/* Type/family dependent function prototypes */ - -#define type_pf_data_equal TOKEN(TYPE, PF, _data_equal) -#define type_pf_data_isnull TOKEN(TYPE, PF, _data_isnull) -#define type_pf_data_copy TOKEN(TYPE, PF, _data_copy) -#define type_pf_data_zero_out TOKEN(TYPE, PF, _data_zero_out) -#define type_pf_data_netmask TOKEN(TYPE, PF, _data_netmask) -#define type_pf_data_list TOKEN(TYPE, PF, _data_list) -#define type_pf_data_tlist TOKEN(TYPE, PF, _data_tlist) -#define type_pf_data_next TOKEN(TYPE, PF, _data_next) - -#define type_pf_elem TOKEN(TYPE, PF, _elem) -#define type_pf_telem TOKEN(TYPE, PF, _telem) -#define type_pf_data_timeout TOKEN(TYPE, PF, _data_timeout) -#define type_pf_data_expired TOKEN(TYPE, PF, _data_expired) -#define type_pf_data_timeout_set TOKEN(TYPE, PF, _data_timeout_set) - -#define type_pf_elem_add TOKEN(TYPE, PF, _elem_add) -#define type_pf_add TOKEN(TYPE, PF, _add) -#define type_pf_del TOKEN(TYPE, PF, _del) -#define type_pf_test_cidrs TOKEN(TYPE, PF, _test_cidrs) -#define type_pf_test TOKEN(TYPE, PF, _test) - -#define type_pf_elem_tadd TOKEN(TYPE, PF, _elem_tadd) -#define type_pf_del_telem TOKEN(TYPE, PF, _ahash_del_telem) -#define type_pf_expire TOKEN(TYPE, PF, _expire) -#define type_pf_tadd TOKEN(TYPE, PF, _tadd) -#define type_pf_tdel TOKEN(TYPE, PF, _tdel) -#define type_pf_ttest_cidrs TOKEN(TYPE, PF, _ahash_ttest_cidrs) -#define type_pf_ttest TOKEN(TYPE, PF, _ahash_ttest) - -#define type_pf_resize TOKEN(TYPE, PF, _resize) -#define type_pf_tresize TOKEN(TYPE, PF, _tresize) -#define type_pf_flush ip_set_hash_flush -#define type_pf_destroy ip_set_hash_destroy -#define type_pf_head TOKEN(TYPE, PF, _head) -#define type_pf_list TOKEN(TYPE, PF, _list) -#define type_pf_tlist TOKEN(TYPE, PF, _tlist) -#define type_pf_same_set TOKEN(TYPE, PF, _same_set) -#define type_pf_kadt TOKEN(TYPE, PF, _kadt) -#define type_pf_uadt TOKEN(TYPE, PF, _uadt) -#define type_pf_gc TOKEN(TYPE, PF, _gc) -#define type_pf_gc_init TOKEN(TYPE, PF, _gc_init) -#define type_pf_variant TOKEN(TYPE, PF, _variant) -#define type_pf_tvariant TOKEN(TYPE, PF, _tvariant) - -/* Flavour without timeout */ - -/* Get the ith element from the array block n */ -#define ahash_data(n, i) \ - ((struct type_pf_elem *)((n)->value) + (i)) - -/* Add an element to the hash table when resizing the set: - * we spare the maintenance of the internal counters. */ -static int -type_pf_elem_add(struct hbucket *n, const struct type_pf_elem *value, - u8 ahash_max) -{ - if (n->pos >= n->size) { - void *tmp; - - if (n->size >= ahash_max) - /* Trigger rehashing */ - return -EAGAIN; - - tmp = kzalloc((n->size + AHASH_INIT_SIZE) - * sizeof(struct type_pf_elem), - GFP_ATOMIC); - if (!tmp) - return -ENOMEM; - if (n->size) { - memcpy(tmp, n->value, - sizeof(struct type_pf_elem) * n->size); - kfree(n->value); - } - n->value = tmp; - n->size += AHASH_INIT_SIZE; - } - type_pf_data_copy(ahash_data(n, n->pos++), value); - return 0; -} - -/* Resize a hash: create a new hash table with doubling the hashsize - * and inserting the elements to it. Repeat until we succeed or - * fail due to memory pressures. */ -static int -type_pf_resize(struct ip_set *set, bool retried) -{ - struct ip_set_hash *h = set->data; - struct htable *t, *orig = h->table; - u8 htable_bits = orig->htable_bits; - const struct type_pf_elem *data; - struct hbucket *n, *m; - u32 i, j; - int ret; - -retry: - ret = 0; - htable_bits++; - pr_debug("attempt to resize set %s from %u to %u, t %p\n", - set->name, orig->htable_bits, htable_bits, orig); - if (!htable_bits) - /* In case we have plenty of memory :-) */ - return -IPSET_ERR_HASH_FULL; - t = ip_set_alloc(sizeof(*t) - + jhash_size(htable_bits) * sizeof(struct hbucket)); - if (!t) - return -ENOMEM; - t->htable_bits = htable_bits; - - read_lock_bh(&set->lock); - for (i = 0; i < jhash_size(orig->htable_bits); i++) { - n = hbucket(orig, i); - for (j = 0; j < n->pos; j++) { - data = ahash_data(n, j); - m = hbucket(t, HKEY(data, h->initval, htable_bits)); - ret = type_pf_elem_add(m, data, AHASH_MAX(h)); - if (ret < 0) { - read_unlock_bh(&set->lock); - ahash_destroy(t); - if (ret == -EAGAIN) - goto retry; - return ret; - } - } - } - - rcu_assign_pointer(h->table, t); - read_unlock_bh(&set->lock); - - /* Give time to other readers of the set */ - synchronize_rcu_bh(); - - pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name, - orig->htable_bits, orig, t->htable_bits, t); - ahash_destroy(orig); - - return 0; -} - -static inline void -type_pf_data_next(struct ip_set_hash *h, const struct type_pf_elem *d); - -/* Add an element to a hash and update the internal counters when succeeded, - * otherwise report the proper error code. */ -static int -type_pf_add(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t; - const struct type_pf_elem *d = value; - struct hbucket *n; - int i, ret = 0; - u32 key, multi = 0; - - if (h->elements >= h->maxelem) - return -IPSET_ERR_HASH_FULL; - - rcu_read_lock_bh(); - t = rcu_dereference_bh(h->table); - key = HKEY(value, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) - if (type_pf_data_equal(ahash_data(n, i), d, &multi)) { - ret = -IPSET_ERR_EXIST; - goto out; - } - TUNE_AHASH_MAX(h, multi); - ret = type_pf_elem_add(n, value, AHASH_MAX(h)); - if (ret != 0) { - if (ret == -EAGAIN) - type_pf_data_next(h, d); - goto out; - } - -#ifdef IP_SET_HASH_WITH_NETS - add_cidr(h, d->cidr, HOST_MASK); -#endif - h->elements++; -out: - rcu_read_unlock_bh(); - return ret; -} - -/* Delete an element from the hash: swap it with the last element - * and free up space if possible. - */ -static int -type_pf_del(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - const struct type_pf_elem *d = value; - struct hbucket *n; - int i; - struct type_pf_elem *data; - u32 key, multi = 0; - - key = HKEY(value, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_data(n, i); - if (!type_pf_data_equal(data, d, &multi)) - continue; - if (i != n->pos - 1) - /* Not last one */ - type_pf_data_copy(data, ahash_data(n, n->pos - 1)); - - n->pos--; - h->elements--; -#ifdef IP_SET_HASH_WITH_NETS - del_cidr(h, d->cidr, HOST_MASK); -#endif - if (n->pos + AHASH_INIT_SIZE < n->size) { - void *tmp = kzalloc((n->size - AHASH_INIT_SIZE) - * sizeof(struct type_pf_elem), - GFP_ATOMIC); - if (!tmp) - return 0; - n->size -= AHASH_INIT_SIZE; - memcpy(tmp, n->value, - n->size * sizeof(struct type_pf_elem)); - kfree(n->value); - n->value = tmp; - } - return 0; - } - - return -IPSET_ERR_EXIST; -} - -#ifdef IP_SET_HASH_WITH_NETS - -/* Special test function which takes into account the different network - * sizes added to the set */ -static int -type_pf_test_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - struct hbucket *n; - const struct type_pf_elem *data; - int i, j = 0; - u32 key, multi = 0; - u8 host_mask = SET_HOST_MASK(set->family); - - pr_debug("test by nets\n"); - for (; j < host_mask && h->nets[j].cidr && !multi; j++) { - type_pf_data_netmask(d, h->nets[j].cidr); - key = HKEY(d, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_data(n, i); - if (type_pf_data_equal(data, d, &multi)) - return 1; - } - } - return 0; -} -#endif - -/* Test whether the element is added to the set */ -static int -type_pf_test(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - struct type_pf_elem *d = value; - struct hbucket *n; - const struct type_pf_elem *data; - int i; - u32 key, multi = 0; - -#ifdef IP_SET_HASH_WITH_NETS - /* If we test an IP address and not a network address, - * try all possible network sizes */ - if (d->cidr == SET_HOST_MASK(set->family)) - return type_pf_test_cidrs(set, d, timeout); -#endif - - key = HKEY(d, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_data(n, i); - if (type_pf_data_equal(data, d, &multi)) - return 1; - } - return 0; -} - -/* Reply a HEADER request: fill out the header part of the set */ -static int -type_pf_head(struct ip_set *set, struct sk_buff *skb) -{ - const struct ip_set_hash *h = set->data; - struct nlattr *nested; - size_t memsize; - - read_lock_bh(&set->lock); - memsize = ahash_memsize(h, with_timeout(h->timeout) - ? sizeof(struct type_pf_telem) - : sizeof(struct type_pf_elem), - set->family == AF_INET ? 32 : 128); - read_unlock_bh(&set->lock); - - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) - goto nla_put_failure; - NLA_PUT_NET32(skb, IPSET_ATTR_HASHSIZE, - htonl(jhash_size(h->table->htable_bits))); - NLA_PUT_NET32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem)); -#ifdef IP_SET_HASH_WITH_NETMASK - if (h->netmask != HOST_MASK) - NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, h->netmask); -#endif - NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); - NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)); - if (with_timeout(h->timeout)) - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout)); - ipset_nest_end(skb, nested); - - return 0; -nla_put_failure: - return -EMSGSIZE; -} - -/* Reply a LIST/SAVE request: dump the elements of the specified set */ -static int -type_pf_list(const struct ip_set *set, - struct sk_buff *skb, struct netlink_callback *cb) -{ - const struct ip_set_hash *h = set->data; - const struct htable *t = h->table; - struct nlattr *atd, *nested; - const struct hbucket *n; - const struct type_pf_elem *data; - u32 first = cb->args[2]; - /* We assume that one hash bucket fills into one page */ - void *incomplete; - int i; - - atd = ipset_nest_start(skb, IPSET_ATTR_ADT); - if (!atd) - return -EMSGSIZE; - pr_debug("list hash set %s\n", set->name); - for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) { - incomplete = skb_tail_pointer(skb); - n = hbucket(t, cb->args[2]); - pr_debug("cb->args[2]: %lu, t %p n %p\n", cb->args[2], t, n); - for (i = 0; i < n->pos; i++) { - data = ahash_data(n, i); - pr_debug("list hash %lu hbucket %p i %u, data %p\n", - cb->args[2], n, i, data); - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) { - if (cb->args[2] == first) { - nla_nest_cancel(skb, atd); - return -EMSGSIZE; - } else - goto nla_put_failure; - } - if (type_pf_data_list(skb, data)) - goto nla_put_failure; - ipset_nest_end(skb, nested); - } - } - ipset_nest_end(skb, atd); - /* Set listing finished */ - cb->args[2] = 0; - - return 0; - -nla_put_failure: - nlmsg_trim(skb, incomplete); - ipset_nest_end(skb, atd); - if (unlikely(first == cb->args[2])) { - pr_warning("Can't list set %s: one bucket does not fit into " - "a message. Please report it!\n", set->name); - cb->args[2] = 0; - return -EMSGSIZE; - } - return 0; -} - -static int -type_pf_kadt(struct ip_set *set, const struct sk_buff * skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt); -static int -type_pf_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried); - -static const struct ip_set_type_variant type_pf_variant = { - .kadt = type_pf_kadt, - .uadt = type_pf_uadt, - .adt = { - [IPSET_ADD] = type_pf_add, - [IPSET_DEL] = type_pf_del, - [IPSET_TEST] = type_pf_test, - }, - .destroy = type_pf_destroy, - .flush = type_pf_flush, - .head = type_pf_head, - .list = type_pf_list, - .resize = type_pf_resize, - .same_set = type_pf_same_set, -}; - -/* Flavour with timeout support */ - -#define ahash_tdata(n, i) \ - (struct type_pf_elem *)((struct type_pf_telem *)((n)->value) + (i)) - -static inline u32 -type_pf_data_timeout(const struct type_pf_elem *data) -{ - const struct type_pf_telem *tdata = - (const struct type_pf_telem *) data; - - return tdata->timeout; -} - -static inline bool -type_pf_data_expired(const struct type_pf_elem *data) -{ - const struct type_pf_telem *tdata = - (const struct type_pf_telem *) data; - - return ip_set_timeout_expired(tdata->timeout); -} - -static inline void -type_pf_data_timeout_set(struct type_pf_elem *data, u32 timeout) -{ - struct type_pf_telem *tdata = (struct type_pf_telem *) data; - - tdata->timeout = ip_set_timeout_set(timeout); -} - -static int -type_pf_elem_tadd(struct hbucket *n, const struct type_pf_elem *value, - u8 ahash_max, u32 timeout) -{ - struct type_pf_elem *data; - - if (n->pos >= n->size) { - void *tmp; - - if (n->size >= ahash_max) - /* Trigger rehashing */ - return -EAGAIN; - - tmp = kzalloc((n->size + AHASH_INIT_SIZE) - * sizeof(struct type_pf_telem), - GFP_ATOMIC); - if (!tmp) - return -ENOMEM; - if (n->size) { - memcpy(tmp, n->value, - sizeof(struct type_pf_telem) * n->size); - kfree(n->value); - } - n->value = tmp; - n->size += AHASH_INIT_SIZE; - } - data = ahash_tdata(n, n->pos++); - type_pf_data_copy(data, value); - type_pf_data_timeout_set(data, timeout); - return 0; -} - -/* Delete expired elements from the hashtable */ -static void -type_pf_expire(struct ip_set_hash *h) -{ - struct htable *t = h->table; - struct hbucket *n; - struct type_pf_elem *data; - u32 i; - int j; - - for (i = 0; i < jhash_size(t->htable_bits); i++) { - n = hbucket(t, i); - for (j = 0; j < n->pos; j++) { - data = ahash_tdata(n, j); - if (type_pf_data_expired(data)) { - pr_debug("expired %u/%u\n", i, j); -#ifdef IP_SET_HASH_WITH_NETS - del_cidr(h, data->cidr, HOST_MASK); -#endif - if (j != n->pos - 1) - /* Not last one */ - type_pf_data_copy(data, - ahash_tdata(n, n->pos - 1)); - n->pos--; - h->elements--; - } - } - if (n->pos + AHASH_INIT_SIZE < n->size) { - void *tmp = kzalloc((n->size - AHASH_INIT_SIZE) - * sizeof(struct type_pf_telem), - GFP_ATOMIC); - if (!tmp) - /* Still try to delete expired elements */ - continue; - n->size -= AHASH_INIT_SIZE; - memcpy(tmp, n->value, - n->size * sizeof(struct type_pf_telem)); - kfree(n->value); - n->value = tmp; - } - } -} - -static int -type_pf_tresize(struct ip_set *set, bool retried) -{ - struct ip_set_hash *h = set->data; - struct htable *t, *orig = h->table; - u8 htable_bits = orig->htable_bits; - const struct type_pf_elem *data; - struct hbucket *n, *m; - u32 i, j; - int ret; - - /* Try to cleanup once */ - if (!retried) { - i = h->elements; - write_lock_bh(&set->lock); - type_pf_expire(set->data); - write_unlock_bh(&set->lock); - if (h->elements < i) - return 0; - } - -retry: - ret = 0; - htable_bits++; - if (!htable_bits) - /* In case we have plenty of memory :-) */ - return -IPSET_ERR_HASH_FULL; - t = ip_set_alloc(sizeof(*t) - + jhash_size(htable_bits) * sizeof(struct hbucket)); - if (!t) - return -ENOMEM; - t->htable_bits = htable_bits; - - read_lock_bh(&set->lock); - for (i = 0; i < jhash_size(orig->htable_bits); i++) { - n = hbucket(orig, i); - for (j = 0; j < n->pos; j++) { - data = ahash_tdata(n, j); - m = hbucket(t, HKEY(data, h->initval, htable_bits)); - ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), - type_pf_data_timeout(data)); - if (ret < 0) { - read_unlock_bh(&set->lock); - ahash_destroy(t); - if (ret == -EAGAIN) - goto retry; - return ret; - } - } - } - - rcu_assign_pointer(h->table, t); - read_unlock_bh(&set->lock); - - /* Give time to other readers of the set */ - synchronize_rcu_bh(); - - ahash_destroy(orig); - - return 0; -} - -static int -type_pf_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - const struct type_pf_elem *d = value; - struct hbucket *n; - struct type_pf_elem *data; - int ret = 0, i, j = AHASH_MAX(h) + 1; - bool flag_exist = flags & IPSET_FLAG_EXIST; - u32 key, multi = 0; - - if (h->elements >= h->maxelem) - /* FIXME: when set is full, we slow down here */ - type_pf_expire(h); - if (h->elements >= h->maxelem) - return -IPSET_ERR_HASH_FULL; - - rcu_read_lock_bh(); - t = rcu_dereference_bh(h->table); - key = HKEY(d, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_tdata(n, i); - if (type_pf_data_equal(data, d, &multi)) { - if (type_pf_data_expired(data) || flag_exist) - j = i; - else { - ret = -IPSET_ERR_EXIST; - goto out; - } - } else if (j == AHASH_MAX(h) + 1 && - type_pf_data_expired(data)) - j = i; - } - if (j != AHASH_MAX(h) + 1) { - data = ahash_tdata(n, j); -#ifdef IP_SET_HASH_WITH_NETS - del_cidr(h, data->cidr, HOST_MASK); - add_cidr(h, d->cidr, HOST_MASK); -#endif - type_pf_data_copy(data, d); - type_pf_data_timeout_set(data, timeout); - goto out; - } - TUNE_AHASH_MAX(h, multi); - ret = type_pf_elem_tadd(n, d, AHASH_MAX(h), timeout); - if (ret != 0) { - if (ret == -EAGAIN) - type_pf_data_next(h, d); - goto out; - } - -#ifdef IP_SET_HASH_WITH_NETS - add_cidr(h, d->cidr, HOST_MASK); -#endif - h->elements++; -out: - rcu_read_unlock_bh(); - return ret; -} - -static int -type_pf_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - const struct type_pf_elem *d = value; - struct hbucket *n; - int i; - struct type_pf_elem *data; - u32 key, multi = 0; - - key = HKEY(value, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_tdata(n, i); - if (!type_pf_data_equal(data, d, &multi)) - continue; - if (type_pf_data_expired(data)) - return -IPSET_ERR_EXIST; - if (i != n->pos - 1) - /* Not last one */ - type_pf_data_copy(data, ahash_tdata(n, n->pos - 1)); - - n->pos--; - h->elements--; -#ifdef IP_SET_HASH_WITH_NETS - del_cidr(h, d->cidr, HOST_MASK); -#endif - if (n->pos + AHASH_INIT_SIZE < n->size) { - void *tmp = kzalloc((n->size - AHASH_INIT_SIZE) - * sizeof(struct type_pf_telem), - GFP_ATOMIC); - if (!tmp) - return 0; - n->size -= AHASH_INIT_SIZE; - memcpy(tmp, n->value, - n->size * sizeof(struct type_pf_telem)); - kfree(n->value); - n->value = tmp; - } - return 0; - } - - return -IPSET_ERR_EXIST; -} - -#ifdef IP_SET_HASH_WITH_NETS -static int -type_pf_ttest_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - struct type_pf_elem *data; - struct hbucket *n; - int i, j = 0; - u32 key, multi = 0; - u8 host_mask = SET_HOST_MASK(set->family); - - for (; j < host_mask && h->nets[j].cidr && !multi; j++) { - type_pf_data_netmask(d, h->nets[j].cidr); - key = HKEY(d, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_tdata(n, i); - if (type_pf_data_equal(data, d, &multi)) - return !type_pf_data_expired(data); - } - } - return 0; -} -#endif - -static int -type_pf_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - struct type_pf_elem *data, *d = value; - struct hbucket *n; - int i; - u32 key, multi = 0; - -#ifdef IP_SET_HASH_WITH_NETS - if (d->cidr == SET_HOST_MASK(set->family)) - return type_pf_ttest_cidrs(set, d, timeout); -#endif - key = HKEY(d, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_tdata(n, i); - if (type_pf_data_equal(data, d, &multi)) - return !type_pf_data_expired(data); - } - return 0; -} - -static int -type_pf_tlist(const struct ip_set *set, - struct sk_buff *skb, struct netlink_callback *cb) -{ - const struct ip_set_hash *h = set->data; - const struct htable *t = h->table; - struct nlattr *atd, *nested; - const struct hbucket *n; - const struct type_pf_elem *data; - u32 first = cb->args[2]; - /* We assume that one hash bucket fills into one page */ - void *incomplete; - int i; - - atd = ipset_nest_start(skb, IPSET_ATTR_ADT); - if (!atd) - return -EMSGSIZE; - for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) { - incomplete = skb_tail_pointer(skb); - n = hbucket(t, cb->args[2]); - for (i = 0; i < n->pos; i++) { - data = ahash_tdata(n, i); - pr_debug("list %p %u\n", n, i); - if (type_pf_data_expired(data)) - continue; - pr_debug("do list %p %u\n", n, i); - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) { - if (cb->args[2] == first) { - nla_nest_cancel(skb, atd); - return -EMSGSIZE; - } else - goto nla_put_failure; - } - if (type_pf_data_tlist(skb, data)) - goto nla_put_failure; - ipset_nest_end(skb, nested); - } - } - ipset_nest_end(skb, atd); - /* Set listing finished */ - cb->args[2] = 0; - - return 0; - -nla_put_failure: - nlmsg_trim(skb, incomplete); - ipset_nest_end(skb, atd); - if (unlikely(first == cb->args[2])) { - pr_warning("Can't list set %s: one bucket does not fit into " - "a message. Please report it!\n", set->name); - cb->args[2] = 0; - return -EMSGSIZE; - } - return 0; -} - -static const struct ip_set_type_variant type_pf_tvariant = { - .kadt = type_pf_kadt, - .uadt = type_pf_uadt, - .adt = { - [IPSET_ADD] = type_pf_tadd, - [IPSET_DEL] = type_pf_tdel, - [IPSET_TEST] = type_pf_ttest, - }, - .destroy = type_pf_destroy, - .flush = type_pf_flush, - .head = type_pf_head, - .list = type_pf_tlist, - .resize = type_pf_tresize, - .same_set = type_pf_same_set, -}; - -static void -type_pf_gc(unsigned long ul_set) -{ - struct ip_set *set = (struct ip_set *) ul_set; - struct ip_set_hash *h = set->data; - - pr_debug("called\n"); - write_lock_bh(&set->lock); - type_pf_expire(h); - write_unlock_bh(&set->lock); - - h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ; - add_timer(&h->gc); -} - -static void -type_pf_gc_init(struct ip_set *set) -{ - struct ip_set_hash *h = set->data; - - init_timer(&h->gc); - h->gc.data = (unsigned long) set; - h->gc.function = type_pf_gc; - h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ; - add_timer(&h->gc); - pr_debug("gc initialized, run in every %u\n", - IPSET_GC_PERIOD(h->timeout)); -} - -#undef HKEY_DATALEN -#undef HKEY -#undef type_pf_data_equal -#undef type_pf_data_isnull -#undef type_pf_data_copy -#undef type_pf_data_zero_out -#undef type_pf_data_list -#undef type_pf_data_tlist - -#undef type_pf_elem -#undef type_pf_telem -#undef type_pf_data_timeout -#undef type_pf_data_expired -#undef type_pf_data_netmask -#undef type_pf_data_timeout_set - -#undef type_pf_elem_add -#undef type_pf_add -#undef type_pf_del -#undef type_pf_test_cidrs -#undef type_pf_test - -#undef type_pf_elem_tadd -#undef type_pf_expire -#undef type_pf_tadd -#undef type_pf_tdel -#undef type_pf_ttest_cidrs -#undef type_pf_ttest - -#undef type_pf_resize -#undef type_pf_tresize -#undef type_pf_flush -#undef type_pf_destroy -#undef type_pf_head -#undef type_pf_list -#undef type_pf_tlist -#undef type_pf_same_set -#undef type_pf_kadt -#undef type_pf_uadt -#undef type_pf_gc -#undef type_pf_gc_init -#undef type_pf_variant -#undef type_pf_tvariant diff --git a/extensions/ipset-6/ip_set_bitmap.h b/extensions/ipset-6/ip_set_bitmap.h deleted file mode 100644 index 61a9e87..0000000 --- a/extensions/ipset-6/ip_set_bitmap.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __IP_SET_BITMAP_H -#define __IP_SET_BITMAP_H - -/* Bitmap type specific error codes */ -enum { - /* The element is out of the range of the set */ - IPSET_ERR_BITMAP_RANGE = IPSET_ERR_TYPE_SPECIFIC, - /* The range exceeds the size limit of the set type */ - IPSET_ERR_BITMAP_RANGE_SIZE, -}; - -#ifdef __KERNEL__ -#define IPSET_BITMAP_MAX_RANGE 0x0000FFFF - -/* Common functions */ - -static inline u32 -range_to_mask(u32 from, u32 to, u8 *bits) -{ - u32 mask = 0xFFFFFFFE; - - *bits = 32; - while (--(*bits) > 0 && mask && (to & mask) != from) - mask <<= 1; - - return mask; -} - -#endif /* __KERNEL__ */ - -#endif /* __IP_SET_BITMAP_H */ diff --git a/extensions/ipset-6/ip_set_bitmap_ip.c b/extensions/ipset-6/ip_set_bitmap_ip.c deleted file mode 100644 index e305653..0000000 --- a/extensions/ipset-6/ip_set_bitmap_ip.c +++ /dev/null @@ -1,587 +0,0 @@ -/* Copyright (C) 2000-2002 Joakim Axelsson - * Patrick Schaaf - * Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module implementing an IP set type: the bitmap:ip type */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pfxlen.h" -#include "ip_set.h" -#include "ip_set_bitmap.h" -#define IP_SET_BITMAP_TIMEOUT -#include "ip_set_timeout.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("bitmap:ip type of IP sets"); -MODULE_ALIAS("ip_set_bitmap:ip"); - -/* Type structure */ -struct bitmap_ip { - void *members; /* the set members */ - u32 first_ip; /* host byte order, included in range */ - u32 last_ip; /* host byte order, included in range */ - u32 elements; /* number of max elements in the set */ - u32 hosts; /* number of hosts in a subnet */ - size_t memsize; /* members size */ - u8 netmask; /* subnet netmask */ - u32 timeout; /* timeout parameter */ - struct timer_list gc; /* garbage collection */ -}; - -/* Base variant */ - -static inline u32 -ip_to_id(const struct bitmap_ip *m, u32 ip) -{ - return ((ip & ip_set_hostmask(m->netmask)) - m->first_ip)/m->hosts; -} - -static int -bitmap_ip_test(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - const struct bitmap_ip *map = set->data; - u16 id = *(u16 *)value; - - return !!test_bit(id, map->members); -} - -static int -bitmap_ip_add(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_ip *map = set->data; - u16 id = *(u16 *)value; - - if (test_and_set_bit(id, map->members)) - return -IPSET_ERR_EXIST; - - return 0; -} - -static int -bitmap_ip_del(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_ip *map = set->data; - u16 id = *(u16 *)value; - - if (!test_and_clear_bit(id, map->members)) - return -IPSET_ERR_EXIST; - - return 0; -} - -static int -bitmap_ip_list(const struct ip_set *set, - struct sk_buff *skb, struct netlink_callback *cb) -{ - const struct bitmap_ip *map = set->data; - struct nlattr *atd, *nested; - u32 id, first = cb->args[2]; - - atd = ipset_nest_start(skb, IPSET_ATTR_ADT); - if (!atd) - return -EMSGSIZE; - for (; cb->args[2] < map->elements; cb->args[2]++) { - id = cb->args[2]; - if (!test_bit(id, map->members)) - continue; - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) { - if (id == first) { - nla_nest_cancel(skb, atd); - return -EMSGSIZE; - } else - goto nla_put_failure; - } - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, - htonl(map->first_ip + id * map->hosts)); - ipset_nest_end(skb, nested); - } - ipset_nest_end(skb, atd); - /* Set listing finished */ - cb->args[2] = 0; - return 0; - -nla_put_failure: - nla_nest_cancel(skb, nested); - ipset_nest_end(skb, atd); - if (unlikely(id == first)) { - cb->args[2] = 0; - return -EMSGSIZE; - } - return 0; -} - -/* Timeout variant */ - -static int -bitmap_ip_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - const struct bitmap_ip *map = set->data; - const unsigned long *members = map->members; - u16 id = *(u16 *)value; - - return ip_set_timeout_test(members[id]); -} - -static int -bitmap_ip_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_ip *map = set->data; - unsigned long *members = map->members; - u16 id = *(u16 *)value; - - if (ip_set_timeout_test(members[id]) && !(flags & IPSET_FLAG_EXIST)) - return -IPSET_ERR_EXIST; - - members[id] = ip_set_timeout_set(timeout); - - return 0; -} - -static int -bitmap_ip_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_ip *map = set->data; - unsigned long *members = map->members; - u16 id = *(u16 *)value; - int ret = -IPSET_ERR_EXIST; - - if (ip_set_timeout_test(members[id])) - ret = 0; - - members[id] = IPSET_ELEM_UNSET; - return ret; -} - -static int -bitmap_ip_tlist(const struct ip_set *set, - struct sk_buff *skb, struct netlink_callback *cb) -{ - const struct bitmap_ip *map = set->data; - struct nlattr *adt, *nested; - u32 id, first = cb->args[2]; - const unsigned long *members = map->members; - - adt = ipset_nest_start(skb, IPSET_ATTR_ADT); - if (!adt) - return -EMSGSIZE; - for (; cb->args[2] < map->elements; cb->args[2]++) { - id = cb->args[2]; - if (!ip_set_timeout_test(members[id])) - continue; - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) { - if (id == first) { - nla_nest_cancel(skb, adt); - return -EMSGSIZE; - } else - goto nla_put_failure; - } - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, - htonl(map->first_ip + id * map->hosts)); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(members[id]))); - ipset_nest_end(skb, nested); - } - ipset_nest_end(skb, adt); - - /* Set listing finished */ - cb->args[2] = 0; - - return 0; - -nla_put_failure: - nla_nest_cancel(skb, nested); - ipset_nest_end(skb, adt); - if (unlikely(id == first)) { - cb->args[2] = 0; - return -EMSGSIZE; - } - return 0; -} - -static int -bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - struct bitmap_ip *map = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - u32 ip; - - ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC)); - if (ip < map->first_ip || ip > map->last_ip) - return -IPSET_ERR_BITMAP_RANGE; - - ip = ip_to_id(map, ip); - - return adtfn(set, &ip, opt_timeout(opt, map), opt->cmdflags); -} - -static int -bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - struct bitmap_ip *map = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - u32 timeout = map->timeout; - u32 ip, ip_to, id; - int ret = 0; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); - if (ret) - return ret; - - if (ip < map->first_ip || ip > map->last_ip) - return -IPSET_ERR_BITMAP_RANGE; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(map->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - if (adt == IPSET_TEST) { - id = ip_to_id(map, ip); - return adtfn(set, &id, timeout, flags); - } - - if (tb[IPSET_ATTR_IP_TO]) { - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); - if (ret) - return ret; - if (ip > ip_to) { - swap(ip, ip_to); - if (ip < map->first_ip) - return -IPSET_ERR_BITMAP_RANGE; - } - } else if (tb[IPSET_ATTR_CIDR]) { - u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - - if (cidr > 32) - return -IPSET_ERR_INVALID_CIDR; - ip_set_mask_from_to(ip, ip_to, cidr); - } else - ip_to = ip; - - if (ip_to > map->last_ip) - return -IPSET_ERR_BITMAP_RANGE; - - for (; !before(ip_to, ip); ip += map->hosts) { - id = ip_to_id(map, ip); - ret = adtfn(set, &id, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - } - return ret; -} - -static void -bitmap_ip_destroy(struct ip_set *set) -{ - struct bitmap_ip *map = set->data; - - if (with_timeout(map->timeout)) - del_timer_sync(&map->gc); - - ip_set_free(map->members); - kfree(map); - - set->data = NULL; -} - -static void -bitmap_ip_flush(struct ip_set *set) -{ - struct bitmap_ip *map = set->data; - - memset(map->members, 0, map->memsize); -} - -static int -bitmap_ip_head(struct ip_set *set, struct sk_buff *skb) -{ - const struct bitmap_ip *map = set->data; - struct nlattr *nested; - - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) - goto nla_put_failure; - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, htonl(map->first_ip)); - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)); - if (map->netmask != 32) - NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, map->netmask); - NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); - NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, - htonl(sizeof(*map) + map->memsize)); - if (with_timeout(map->timeout)) - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout)); - ipset_nest_end(skb, nested); - - return 0; -nla_put_failure: - return -EMSGSIZE; -} - -static bool -bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b) -{ - const struct bitmap_ip *x = a->data; - const struct bitmap_ip *y = b->data; - - return x->first_ip == y->first_ip && - x->last_ip == y->last_ip && - x->netmask == y->netmask && - x->timeout == y->timeout; -} - -static const struct ip_set_type_variant bitmap_ip = { - .kadt = bitmap_ip_kadt, - .uadt = bitmap_ip_uadt, - .adt = { - [IPSET_ADD] = bitmap_ip_add, - [IPSET_DEL] = bitmap_ip_del, - [IPSET_TEST] = bitmap_ip_test, - }, - .destroy = bitmap_ip_destroy, - .flush = bitmap_ip_flush, - .head = bitmap_ip_head, - .list = bitmap_ip_list, - .same_set = bitmap_ip_same_set, -}; - -static const struct ip_set_type_variant bitmap_tip = { - .kadt = bitmap_ip_kadt, - .uadt = bitmap_ip_uadt, - .adt = { - [IPSET_ADD] = bitmap_ip_tadd, - [IPSET_DEL] = bitmap_ip_tdel, - [IPSET_TEST] = bitmap_ip_ttest, - }, - .destroy = bitmap_ip_destroy, - .flush = bitmap_ip_flush, - .head = bitmap_ip_head, - .list = bitmap_ip_tlist, - .same_set = bitmap_ip_same_set, -}; - -static void -bitmap_ip_gc(unsigned long ul_set) -{ - struct ip_set *set = (struct ip_set *) ul_set; - struct bitmap_ip *map = set->data; - unsigned long *table = map->members; - u32 id; - - /* We run parallel with other readers (test element) - * but adding/deleting new entries is locked out */ - read_lock_bh(&set->lock); - for (id = 0; id < map->elements; id++) - if (ip_set_timeout_expired(table[id])) - table[id] = IPSET_ELEM_UNSET; - read_unlock_bh(&set->lock); - - map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; - add_timer(&map->gc); -} - -static void -bitmap_ip_gc_init(struct ip_set *set) -{ - struct bitmap_ip *map = set->data; - - init_timer(&map->gc); - map->gc.data = (unsigned long) set; - map->gc.function = bitmap_ip_gc; - map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; - add_timer(&map->gc); -} - -/* Create bitmap:ip type of sets */ - -static bool -init_map_ip(struct ip_set *set, struct bitmap_ip *map, - u32 first_ip, u32 last_ip, - u32 elements, u32 hosts, u8 netmask) -{ - map->members = ip_set_alloc(map->memsize); - if (!map->members) - return false; - map->first_ip = first_ip; - map->last_ip = last_ip; - map->elements = elements; - map->hosts = hosts; - map->netmask = netmask; - map->timeout = IPSET_NO_TIMEOUT; - - set->data = map; - set->family = NFPROTO_IPV4; - - return true; -} - -static int -bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) -{ - struct bitmap_ip *map; - u32 first_ip, last_ip, hosts, elements; - u8 netmask = 32; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip); - if (ret) - return ret; - - if (tb[IPSET_ATTR_IP_TO]) { - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip); - if (ret) - return ret; - if (first_ip > last_ip) { - u32 tmp = first_ip; - - first_ip = last_ip; - last_ip = tmp; - } - } else if (tb[IPSET_ATTR_CIDR]) { - u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - - if (cidr >= 32) - return -IPSET_ERR_INVALID_CIDR; - ip_set_mask_from_to(first_ip, last_ip, cidr); - } else - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_NETMASK]) { - netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]); - - if (netmask > 32) - return -IPSET_ERR_INVALID_NETMASK; - - first_ip &= ip_set_hostmask(netmask); - last_ip |= ~ip_set_hostmask(netmask); - } - - if (netmask == 32) { - hosts = 1; - elements = last_ip - first_ip + 1; - } else { - u8 mask_bits; - u32 mask; - - mask = range_to_mask(first_ip, last_ip, &mask_bits); - - if ((!mask && (first_ip || last_ip != 0xFFFFFFFF)) || - netmask <= mask_bits) - return -IPSET_ERR_BITMAP_RANGE; - - pr_debug("mask_bits %u, netmask %u\n", mask_bits, netmask); - hosts = 2 << (32 - netmask - 1); - elements = 2 << (netmask - mask_bits - 1); - } - if (elements > IPSET_BITMAP_MAX_RANGE + 1) - return -IPSET_ERR_BITMAP_RANGE_SIZE; - - pr_debug("hosts %u, elements %u\n", hosts, elements); - - map = kzalloc(sizeof(*map), GFP_KERNEL); - if (!map) - return -ENOMEM; - - if (tb[IPSET_ATTR_TIMEOUT]) { - map->memsize = elements * sizeof(unsigned long); - - if (!init_map_ip(set, map, first_ip, last_ip, - elements, hosts, netmask)) { - kfree(map); - return -ENOMEM; - } - - map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - set->variant = &bitmap_tip; - - bitmap_ip_gc_init(set); - } else { - map->memsize = bitmap_bytes(0, elements - 1); - - if (!init_map_ip(set, map, first_ip, last_ip, - elements, hosts, netmask)) { - kfree(map); - return -ENOMEM; - } - - set->variant = &bitmap_ip; - } - return 0; -} - -static struct ip_set_type bitmap_ip_type __read_mostly = { - .name = "bitmap:ip", - .protocol = IPSET_PROTOCOL, - .features = IPSET_TYPE_IP, - .dimension = IPSET_DIM_ONE, - .family = NFPROTO_IPV4, - .revision_min = 0, - .revision_max = 0, - .create = bitmap_ip_create, - .create_policy = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, - [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, - [IPSET_ATTR_NETMASK] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - }, - .adt_policy = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, - [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, - }, - .me = THIS_MODULE, -}; - -static int __init -bitmap_ip_init(void) -{ - return ip_set_type_register(&bitmap_ip_type); -} - -static void __exit -bitmap_ip_fini(void) -{ - ip_set_type_unregister(&bitmap_ip_type); -} - -module_init(bitmap_ip_init); -module_exit(bitmap_ip_fini); diff --git a/extensions/ipset-6/ip_set_bitmap_ipmac.c b/extensions/ipset-6/ip_set_bitmap_ipmac.c deleted file mode 100644 index eaec01d..0000000 --- a/extensions/ipset-6/ip_set_bitmap_ipmac.c +++ /dev/null @@ -1,659 +0,0 @@ -/* Copyright (C) 2000-2002 Joakim Axelsson - * Patrick Schaaf - * Martin Josefsson - * Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module implementing an IP set type: the bitmap:ip,mac type */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pfxlen.h" -#include "ip_set.h" -#include "ip_set_timeout.h" -#include "ip_set_bitmap.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("bitmap:ip,mac type of IP sets"); -MODULE_ALIAS("ip_set_bitmap:ip,mac"); - -enum { - MAC_EMPTY, /* element is not set */ - MAC_FILLED, /* element is set with MAC */ - MAC_UNSET, /* element is set, without MAC */ -}; - -/* Type structure */ -struct bitmap_ipmac { - void *members; /* the set members */ - u32 first_ip; /* host byte order, included in range */ - u32 last_ip; /* host byte order, included in range */ - u32 timeout; /* timeout value */ - struct timer_list gc; /* garbage collector */ - size_t dsize; /* size of element */ -}; - -/* ADT structure for generic function args */ -struct ipmac { - u32 id; /* id in array */ - unsigned char *ether; /* ethernet address */ -}; - -/* Member element without and with timeout */ - -struct ipmac_elem { - unsigned char ether[ETH_ALEN]; - unsigned char match; -} __attribute__ ((aligned)); - -struct ipmac_telem { - unsigned char ether[ETH_ALEN]; - unsigned char match; - unsigned long timeout; -} __attribute__ ((aligned)); - -static inline void * -bitmap_ipmac_elem(const struct bitmap_ipmac *map, u32 id) -{ - return (void *)((char *)map->members + id * map->dsize); -} - -static inline bool -bitmap_timeout(const struct bitmap_ipmac *map, u32 id) -{ - const struct ipmac_telem *elem = bitmap_ipmac_elem(map, id); - - return ip_set_timeout_test(elem->timeout); -} - -static inline bool -bitmap_expired(const struct bitmap_ipmac *map, u32 id) -{ - const struct ipmac_telem *elem = bitmap_ipmac_elem(map, id); - - return ip_set_timeout_expired(elem->timeout); -} - -static inline int -bitmap_ipmac_exist(const struct ipmac_telem *elem) -{ - return elem->match == MAC_UNSET || - (elem->match == MAC_FILLED && - !ip_set_timeout_expired(elem->timeout)); -} - -/* Base variant */ - -static int -bitmap_ipmac_test(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - const struct bitmap_ipmac *map = set->data; - const struct ipmac *data = value; - const struct ipmac_elem *elem = bitmap_ipmac_elem(map, data->id); - - switch (elem->match) { - case MAC_UNSET: - /* Trigger kernel to fill out the ethernet address */ - return -EAGAIN; - case MAC_FILLED: - return data->ether == NULL || - compare_ether_addr(data->ether, elem->ether) == 0; - } - return 0; -} - -static int -bitmap_ipmac_add(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_ipmac *map = set->data; - const struct ipmac *data = value; - struct ipmac_elem *elem = bitmap_ipmac_elem(map, data->id); - - switch (elem->match) { - case MAC_UNSET: - if (!data->ether) - /* Already added without ethernet address */ - return -IPSET_ERR_EXIST; - /* Fill the MAC address */ - memcpy(elem->ether, data->ether, ETH_ALEN); - elem->match = MAC_FILLED; - break; - case MAC_FILLED: - return -IPSET_ERR_EXIST; - case MAC_EMPTY: - if (data->ether) { - memcpy(elem->ether, data->ether, ETH_ALEN); - elem->match = MAC_FILLED; - } else - elem->match = MAC_UNSET; - } - - return 0; -} - -static int -bitmap_ipmac_del(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_ipmac *map = set->data; - const struct ipmac *data = value; - struct ipmac_elem *elem = bitmap_ipmac_elem(map, data->id); - - if (elem->match == MAC_EMPTY) - return -IPSET_ERR_EXIST; - - elem->match = MAC_EMPTY; - - return 0; -} - -static int -bitmap_ipmac_list(const struct ip_set *set, - struct sk_buff *skb, struct netlink_callback *cb) -{ - const struct bitmap_ipmac *map = set->data; - const struct ipmac_elem *elem; - struct nlattr *atd, *nested; - u32 id, first = cb->args[2]; - u32 last = map->last_ip - map->first_ip; - - atd = ipset_nest_start(skb, IPSET_ATTR_ADT); - if (!atd) - return -EMSGSIZE; - for (; cb->args[2] <= last; cb->args[2]++) { - id = cb->args[2]; - elem = bitmap_ipmac_elem(map, id); - if (elem->match == MAC_EMPTY) - continue; - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) { - if (id == first) { - nla_nest_cancel(skb, atd); - return -EMSGSIZE; - } else - goto nla_put_failure; - } - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, - htonl(map->first_ip + id)); - if (elem->match == MAC_FILLED) - NLA_PUT(skb, IPSET_ATTR_ETHER, ETH_ALEN, - elem->ether); - ipset_nest_end(skb, nested); - } - ipset_nest_end(skb, atd); - /* Set listing finished */ - cb->args[2] = 0; - - return 0; - -nla_put_failure: - nla_nest_cancel(skb, nested); - ipset_nest_end(skb, atd); - if (unlikely(id == first)) { - cb->args[2] = 0; - return -EMSGSIZE; - } - return 0; -} - -/* Timeout variant */ - -static int -bitmap_ipmac_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - const struct bitmap_ipmac *map = set->data; - const struct ipmac *data = value; - const struct ipmac_elem *elem = bitmap_ipmac_elem(map, data->id); - - switch (elem->match) { - case MAC_UNSET: - /* Trigger kernel to fill out the ethernet address */ - return -EAGAIN; - case MAC_FILLED: - return (data->ether == NULL || - compare_ether_addr(data->ether, elem->ether) == 0) && - !bitmap_expired(map, data->id); - } - return 0; -} - -static int -bitmap_ipmac_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_ipmac *map = set->data; - const struct ipmac *data = value; - struct ipmac_telem *elem = bitmap_ipmac_elem(map, data->id); - bool flag_exist = flags & IPSET_FLAG_EXIST; - - switch (elem->match) { - case MAC_UNSET: - if (!(data->ether || flag_exist)) - /* Already added without ethernet address */ - return -IPSET_ERR_EXIST; - /* Fill the MAC address and activate the timer */ - memcpy(elem->ether, data->ether, ETH_ALEN); - elem->match = MAC_FILLED; - if (timeout == map->timeout) - /* Timeout was not specified, get stored one */ - timeout = elem->timeout; - elem->timeout = ip_set_timeout_set(timeout); - break; - case MAC_FILLED: - if (!(bitmap_expired(map, data->id) || flag_exist)) - return -IPSET_ERR_EXIST; - /* Fall through */ - case MAC_EMPTY: - if (data->ether) { - memcpy(elem->ether, data->ether, ETH_ALEN); - elem->match = MAC_FILLED; - } else - elem->match = MAC_UNSET; - /* If MAC is unset yet, we store plain timeout value - * because the timer is not activated yet - * and we can reuse it later when MAC is filled out, - * possibly by the kernel */ - elem->timeout = data->ether ? ip_set_timeout_set(timeout) - : timeout; - break; - } - - return 0; -} - -static int -bitmap_ipmac_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_ipmac *map = set->data; - const struct ipmac *data = value; - struct ipmac_telem *elem = bitmap_ipmac_elem(map, data->id); - - if (elem->match == MAC_EMPTY || bitmap_expired(map, data->id)) - return -IPSET_ERR_EXIST; - - elem->match = MAC_EMPTY; - - return 0; -} - -static int -bitmap_ipmac_tlist(const struct ip_set *set, - struct sk_buff *skb, struct netlink_callback *cb) -{ - const struct bitmap_ipmac *map = set->data; - const struct ipmac_telem *elem; - struct nlattr *atd, *nested; - u32 id, first = cb->args[2]; - u32 timeout, last = map->last_ip - map->first_ip; - - atd = ipset_nest_start(skb, IPSET_ATTR_ADT); - if (!atd) - return -EMSGSIZE; - for (; cb->args[2] <= last; cb->args[2]++) { - id = cb->args[2]; - elem = bitmap_ipmac_elem(map, id); - if (!bitmap_ipmac_exist(elem)) - continue; - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) { - if (id == first) { - nla_nest_cancel(skb, atd); - return -EMSGSIZE; - } else - goto nla_put_failure; - } - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, - htonl(map->first_ip + id)); - if (elem->match == MAC_FILLED) - NLA_PUT(skb, IPSET_ATTR_ETHER, ETH_ALEN, - elem->ether); - timeout = elem->match == MAC_UNSET ? elem->timeout - : ip_set_timeout_get(elem->timeout); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(timeout)); - ipset_nest_end(skb, nested); - } - ipset_nest_end(skb, atd); - /* Set listing finished */ - cb->args[2] = 0; - - return 0; - -nla_put_failure: - nla_nest_cancel(skb, nested); - ipset_nest_end(skb, atd); - return -EMSGSIZE; -} - -static int -bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - struct bitmap_ipmac *map = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct ipmac data; - - /* MAC can be src only */ - if (!(opt->flags & IPSET_DIM_TWO_SRC)) - return 0; - - data.id = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC)); - if (data.id < map->first_ip || data.id > map->last_ip) - return -IPSET_ERR_BITMAP_RANGE; - - /* Backward compatibility: we don't check the second flag */ - if (skb_mac_header(skb) < skb->head || - (skb_mac_header(skb) + ETH_HLEN) > skb->data) - return -EINVAL; - - data.id -= map->first_ip; - data.ether = eth_hdr(skb)->h_source; - - return adtfn(set, &data, opt_timeout(opt, map), opt->cmdflags); -} - -static int -bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct bitmap_ipmac *map = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct ipmac data; - u32 timeout = map->timeout; - int ret = 0; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &data.id); - if (ret) - return ret; - - if (data.id < map->first_ip || data.id > map->last_ip) - return -IPSET_ERR_BITMAP_RANGE; - - if (tb[IPSET_ATTR_ETHER]) - data.ether = nla_data(tb[IPSET_ATTR_ETHER]); - else - data.ether = NULL; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(map->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - data.id -= map->first_ip; - - ret = adtfn(set, &data, timeout, flags); - - return ip_set_eexist(ret, flags) ? 0 : ret; -} - -static void -bitmap_ipmac_destroy(struct ip_set *set) -{ - struct bitmap_ipmac *map = set->data; - - if (with_timeout(map->timeout)) - del_timer_sync(&map->gc); - - ip_set_free(map->members); - kfree(map); - - set->data = NULL; -} - -static void -bitmap_ipmac_flush(struct ip_set *set) -{ - struct bitmap_ipmac *map = set->data; - - memset(map->members, 0, - (map->last_ip - map->first_ip + 1) * map->dsize); -} - -static int -bitmap_ipmac_head(struct ip_set *set, struct sk_buff *skb) -{ - const struct bitmap_ipmac *map = set->data; - struct nlattr *nested; - - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) - goto nla_put_failure; - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, htonl(map->first_ip)); - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)); - NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); - NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, - htonl(sizeof(*map) - + (map->last_ip - map->first_ip + 1) * map->dsize)); - if (with_timeout(map->timeout)) - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout)); - ipset_nest_end(skb, nested); - - return 0; -nla_put_failure: - return -EMSGSIZE; -} - -static bool -bitmap_ipmac_same_set(const struct ip_set *a, const struct ip_set *b) -{ - const struct bitmap_ipmac *x = a->data; - const struct bitmap_ipmac *y = b->data; - - return x->first_ip == y->first_ip && - x->last_ip == y->last_ip && - x->timeout == y->timeout; -} - -static const struct ip_set_type_variant bitmap_ipmac = { - .kadt = bitmap_ipmac_kadt, - .uadt = bitmap_ipmac_uadt, - .adt = { - [IPSET_ADD] = bitmap_ipmac_add, - [IPSET_DEL] = bitmap_ipmac_del, - [IPSET_TEST] = bitmap_ipmac_test, - }, - .destroy = bitmap_ipmac_destroy, - .flush = bitmap_ipmac_flush, - .head = bitmap_ipmac_head, - .list = bitmap_ipmac_list, - .same_set = bitmap_ipmac_same_set, -}; - -static const struct ip_set_type_variant bitmap_tipmac = { - .kadt = bitmap_ipmac_kadt, - .uadt = bitmap_ipmac_uadt, - .adt = { - [IPSET_ADD] = bitmap_ipmac_tadd, - [IPSET_DEL] = bitmap_ipmac_tdel, - [IPSET_TEST] = bitmap_ipmac_ttest, - }, - .destroy = bitmap_ipmac_destroy, - .flush = bitmap_ipmac_flush, - .head = bitmap_ipmac_head, - .list = bitmap_ipmac_tlist, - .same_set = bitmap_ipmac_same_set, -}; - -static void -bitmap_ipmac_gc(unsigned long ul_set) -{ - struct ip_set *set = (struct ip_set *) ul_set; - struct bitmap_ipmac *map = set->data; - struct ipmac_telem *elem; - u32 id, last = map->last_ip - map->first_ip; - - /* We run parallel with other readers (test element) - * but adding/deleting new entries is locked out */ - read_lock_bh(&set->lock); - for (id = 0; id <= last; id++) { - elem = bitmap_ipmac_elem(map, id); - if (elem->match == MAC_FILLED && - ip_set_timeout_expired(elem->timeout)) - elem->match = MAC_EMPTY; - } - read_unlock_bh(&set->lock); - - map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; - add_timer(&map->gc); -} - -static void -bitmap_ipmac_gc_init(struct ip_set *set) -{ - struct bitmap_ipmac *map = set->data; - - init_timer(&map->gc); - map->gc.data = (unsigned long) set; - map->gc.function = bitmap_ipmac_gc; - map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; - add_timer(&map->gc); -} - -/* Create bitmap:ip,mac type of sets */ - -static bool -init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map, - u32 first_ip, u32 last_ip) -{ - map->members = ip_set_alloc((last_ip - first_ip + 1) * map->dsize); - if (!map->members) - return false; - map->first_ip = first_ip; - map->last_ip = last_ip; - map->timeout = IPSET_NO_TIMEOUT; - - set->data = map; - set->family = NFPROTO_IPV4; - - return true; -} - -static int -bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], - u32 flags) -{ - u32 first_ip, last_ip, elements; - struct bitmap_ipmac *map; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip); - if (ret) - return ret; - - if (tb[IPSET_ATTR_IP_TO]) { - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &last_ip); - if (ret) - return ret; - if (first_ip > last_ip) { - u32 tmp = first_ip; - - first_ip = last_ip; - last_ip = tmp; - } - } else if (tb[IPSET_ATTR_CIDR]) { - u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - - if (cidr >= 32) - return -IPSET_ERR_INVALID_CIDR; - ip_set_mask_from_to(first_ip, last_ip, cidr); - } else - return -IPSET_ERR_PROTOCOL; - - elements = last_ip - first_ip + 1; - - if (elements > IPSET_BITMAP_MAX_RANGE + 1) - return -IPSET_ERR_BITMAP_RANGE_SIZE; - - map = kzalloc(sizeof(*map), GFP_KERNEL); - if (!map) - return -ENOMEM; - - if (tb[IPSET_ATTR_TIMEOUT]) { - map->dsize = sizeof(struct ipmac_telem); - - if (!init_map_ipmac(set, map, first_ip, last_ip)) { - kfree(map); - return -ENOMEM; - } - - map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - - set->variant = &bitmap_tipmac; - - bitmap_ipmac_gc_init(set); - } else { - map->dsize = sizeof(struct ipmac_elem); - - if (!init_map_ipmac(set, map, first_ip, last_ip)) { - kfree(map); - return -ENOMEM; - } - set->variant = &bitmap_ipmac; - - } - return 0; -} - -static struct ip_set_type bitmap_ipmac_type = { - .name = "bitmap:ip,mac", - .protocol = IPSET_PROTOCOL, - .features = IPSET_TYPE_IP | IPSET_TYPE_MAC, - .dimension = IPSET_DIM_TWO, - .family = NFPROTO_IPV4, - .revision_min = 0, - .revision_max = 0, - .create = bitmap_ipmac_create, - .create_policy = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, - [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - }, - .adt_policy = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_ETHER] = { .type = NLA_BINARY, - .len = ETH_ALEN }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, - }, - .me = THIS_MODULE, -}; - -static int __init -bitmap_ipmac_init(void) -{ - return ip_set_type_register(&bitmap_ipmac_type); -} - -static void __exit -bitmap_ipmac_fini(void) -{ - ip_set_type_unregister(&bitmap_ipmac_type); -} - -module_init(bitmap_ipmac_init); -module_exit(bitmap_ipmac_fini); diff --git a/extensions/ipset-6/ip_set_bitmap_port.c b/extensions/ipset-6/ip_set_bitmap_port.c deleted file mode 100644 index fd43aa7..0000000 --- a/extensions/ipset-6/ip_set_bitmap_port.c +++ /dev/null @@ -1,517 +0,0 @@ -/* Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module implementing an IP set type: the bitmap:port type */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ip_set.h" -#include "ip_set_bitmap.h" -#include "ip_set_getport.h" -#define IP_SET_BITMAP_TIMEOUT -#include "ip_set_timeout.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("bitmap:port type of IP sets"); -MODULE_ALIAS("ip_set_bitmap:port"); - -/* Type structure */ -struct bitmap_port { - void *members; /* the set members */ - u16 first_port; /* host byte order, included in range */ - u16 last_port; /* host byte order, included in range */ - size_t memsize; /* members size */ - u32 timeout; /* timeout parameter */ - struct timer_list gc; /* garbage collection */ -}; - -/* Base variant */ - -static int -bitmap_port_test(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - const struct bitmap_port *map = set->data; - u16 id = *(u16 *)value; - - return !!test_bit(id, map->members); -} - -static int -bitmap_port_add(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_port *map = set->data; - u16 id = *(u16 *)value; - - if (test_and_set_bit(id, map->members)) - return -IPSET_ERR_EXIST; - - return 0; -} - -static int -bitmap_port_del(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_port *map = set->data; - u16 id = *(u16 *)value; - - if (!test_and_clear_bit(id, map->members)) - return -IPSET_ERR_EXIST; - - return 0; -} - -static int -bitmap_port_list(const struct ip_set *set, - struct sk_buff *skb, struct netlink_callback *cb) -{ - const struct bitmap_port *map = set->data; - struct nlattr *atd, *nested; - u16 id, first = cb->args[2]; - u16 last = map->last_port - map->first_port; - - atd = ipset_nest_start(skb, IPSET_ATTR_ADT); - if (!atd) - return -EMSGSIZE; - for (; cb->args[2] <= last; cb->args[2]++) { - id = cb->args[2]; - if (!test_bit(id, map->members)) - continue; - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) { - if (id == first) { - nla_nest_cancel(skb, atd); - return -EMSGSIZE; - } else - goto nla_put_failure; - } - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, - htons(map->first_port + id)); - ipset_nest_end(skb, nested); - } - ipset_nest_end(skb, atd); - /* Set listing finished */ - cb->args[2] = 0; - - return 0; - -nla_put_failure: - nla_nest_cancel(skb, nested); - ipset_nest_end(skb, atd); - if (unlikely(id == first)) { - cb->args[2] = 0; - return -EMSGSIZE; - } - return 0; -} - -/* Timeout variant */ - -static int -bitmap_port_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - const struct bitmap_port *map = set->data; - const unsigned long *members = map->members; - u16 id = *(u16 *)value; - - return ip_set_timeout_test(members[id]); -} - -static int -bitmap_port_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_port *map = set->data; - unsigned long *members = map->members; - u16 id = *(u16 *)value; - - if (ip_set_timeout_test(members[id]) && !(flags & IPSET_FLAG_EXIST)) - return -IPSET_ERR_EXIST; - - members[id] = ip_set_timeout_set(timeout); - - return 0; -} - -static int -bitmap_port_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct bitmap_port *map = set->data; - unsigned long *members = map->members; - u16 id = *(u16 *)value; - int ret = -IPSET_ERR_EXIST; - - if (ip_set_timeout_test(members[id])) - ret = 0; - - members[id] = IPSET_ELEM_UNSET; - return ret; -} - -static int -bitmap_port_tlist(const struct ip_set *set, - struct sk_buff *skb, struct netlink_callback *cb) -{ - const struct bitmap_port *map = set->data; - struct nlattr *adt, *nested; - u16 id, first = cb->args[2]; - u16 last = map->last_port - map->first_port; - const unsigned long *members = map->members; - - adt = ipset_nest_start(skb, IPSET_ATTR_ADT); - if (!adt) - return -EMSGSIZE; - for (; cb->args[2] <= last; cb->args[2]++) { - id = cb->args[2]; - if (!ip_set_timeout_test(members[id])) - continue; - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) { - if (id == first) { - nla_nest_cancel(skb, adt); - return -EMSGSIZE; - } else - goto nla_put_failure; - } - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, - htons(map->first_port + id)); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(members[id]))); - ipset_nest_end(skb, nested); - } - ipset_nest_end(skb, adt); - - /* Set listing finished */ - cb->args[2] = 0; - - return 0; - -nla_put_failure: - nla_nest_cancel(skb, nested); - ipset_nest_end(skb, adt); - if (unlikely(id == first)) { - cb->args[2] = 0; - return -EMSGSIZE; - } - return 0; -} - -static int -bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - struct bitmap_port *map = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - __be16 __port; - u16 port = 0; - - if (!ip_set_get_ip_port(skb, opt->family, - opt->flags & IPSET_DIM_ONE_SRC, &__port)) - return -EINVAL; - - port = ntohs(__port); - - if (port < map->first_port || port > map->last_port) - return -IPSET_ERR_BITMAP_RANGE; - - port -= map->first_port; - - return adtfn(set, &port, opt_timeout(opt, map), opt->cmdflags); -} - -static int -bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - struct bitmap_port *map = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - u32 timeout = map->timeout; - u32 port; /* wraparound */ - u16 id, port_to; - int ret = 0; - - if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - port = ip_set_get_h16(tb[IPSET_ATTR_PORT]); - if (port < map->first_port || port > map->last_port) - return -IPSET_ERR_BITMAP_RANGE; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(map->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - if (adt == IPSET_TEST) { - id = port - map->first_port; - return adtfn(set, &id, timeout, flags); - } - - if (tb[IPSET_ATTR_PORT_TO]) { - port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); - if (port > port_to) { - swap(port, port_to); - if (port < map->first_port) - return -IPSET_ERR_BITMAP_RANGE; - } - } else - port_to = port; - - if (port_to > map->last_port) - return -IPSET_ERR_BITMAP_RANGE; - - for (; port <= port_to; port++) { - id = port - map->first_port; - ret = adtfn(set, &id, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - } - return ret; -} - -static void -bitmap_port_destroy(struct ip_set *set) -{ - struct bitmap_port *map = set->data; - - if (with_timeout(map->timeout)) - del_timer_sync(&map->gc); - - ip_set_free(map->members); - kfree(map); - - set->data = NULL; -} - -static void -bitmap_port_flush(struct ip_set *set) -{ - struct bitmap_port *map = set->data; - - memset(map->members, 0, map->memsize); -} - -static int -bitmap_port_head(struct ip_set *set, struct sk_buff *skb) -{ - const struct bitmap_port *map = set->data; - struct nlattr *nested; - - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) - goto nla_put_failure; - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, htons(map->first_port)); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port)); - NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); - NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, - htonl(sizeof(*map) + map->memsize)); - if (with_timeout(map->timeout)) - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout)); - ipset_nest_end(skb, nested); - - return 0; -nla_put_failure: - return -EMSGSIZE; -} - -static bool -bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b) -{ - const struct bitmap_port *x = a->data; - const struct bitmap_port *y = b->data; - - return x->first_port == y->first_port && - x->last_port == y->last_port && - x->timeout == y->timeout; -} - -static const struct ip_set_type_variant bitmap_port = { - .kadt = bitmap_port_kadt, - .uadt = bitmap_port_uadt, - .adt = { - [IPSET_ADD] = bitmap_port_add, - [IPSET_DEL] = bitmap_port_del, - [IPSET_TEST] = bitmap_port_test, - }, - .destroy = bitmap_port_destroy, - .flush = bitmap_port_flush, - .head = bitmap_port_head, - .list = bitmap_port_list, - .same_set = bitmap_port_same_set, -}; - -static const struct ip_set_type_variant bitmap_tport = { - .kadt = bitmap_port_kadt, - .uadt = bitmap_port_uadt, - .adt = { - [IPSET_ADD] = bitmap_port_tadd, - [IPSET_DEL] = bitmap_port_tdel, - [IPSET_TEST] = bitmap_port_ttest, - }, - .destroy = bitmap_port_destroy, - .flush = bitmap_port_flush, - .head = bitmap_port_head, - .list = bitmap_port_tlist, - .same_set = bitmap_port_same_set, -}; - -static void -bitmap_port_gc(unsigned long ul_set) -{ - struct ip_set *set = (struct ip_set *) ul_set; - struct bitmap_port *map = set->data; - unsigned long *table = map->members; - u32 id; /* wraparound */ - u16 last = map->last_port - map->first_port; - - /* We run parallel with other readers (test element) - * but adding/deleting new entries is locked out */ - read_lock_bh(&set->lock); - for (id = 0; id <= last; id++) - if (ip_set_timeout_expired(table[id])) - table[id] = IPSET_ELEM_UNSET; - read_unlock_bh(&set->lock); - - map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; - add_timer(&map->gc); -} - -static void -bitmap_port_gc_init(struct ip_set *set) -{ - struct bitmap_port *map = set->data; - - init_timer(&map->gc); - map->gc.data = (unsigned long) set; - map->gc.function = bitmap_port_gc; - map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; - add_timer(&map->gc); -} - -/* Create bitmap:ip type of sets */ - -static bool -init_map_port(struct ip_set *set, struct bitmap_port *map, - u16 first_port, u16 last_port) -{ - map->members = ip_set_alloc(map->memsize); - if (!map->members) - return false; - map->first_port = first_port; - map->last_port = last_port; - map->timeout = IPSET_NO_TIMEOUT; - - set->data = map; - set->family = NFPROTO_UNSPEC; - - return true; -} - -static int -bitmap_port_create(struct ip_set *set, struct nlattr *tb[], - u32 flags) -{ - struct bitmap_port *map; - u16 first_port, last_port; - - if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || - !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]); - last_port = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); - if (first_port > last_port) { - u16 tmp = first_port; - - first_port = last_port; - last_port = tmp; - } - - map = kzalloc(sizeof(*map), GFP_KERNEL); - if (!map) - return -ENOMEM; - - if (tb[IPSET_ATTR_TIMEOUT]) { - map->memsize = (last_port - first_port + 1) - * sizeof(unsigned long); - - if (!init_map_port(set, map, first_port, last_port)) { - kfree(map); - return -ENOMEM; - } - - map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - set->variant = &bitmap_tport; - - bitmap_port_gc_init(set); - } else { - map->memsize = bitmap_bytes(0, last_port - first_port); - pr_debug("memsize: %zu\n", map->memsize); - if (!init_map_port(set, map, first_port, last_port)) { - kfree(map); - return -ENOMEM; - } - - set->variant = &bitmap_port; - } - return 0; -} - -static struct ip_set_type bitmap_port_type = { - .name = "bitmap:port", - .protocol = IPSET_PROTOCOL, - .features = IPSET_TYPE_PORT, - .dimension = IPSET_DIM_ONE, - .family = NFPROTO_UNSPEC, - .revision_min = 0, - .revision_max = 0, - .create = bitmap_port_create, - .create_policy = { - [IPSET_ATTR_PORT] = { .type = NLA_U16 }, - [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - }, - .adt_policy = { - [IPSET_ATTR_PORT] = { .type = NLA_U16 }, - [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, - }, - .me = THIS_MODULE, -}; - -static int __init -bitmap_port_init(void) -{ - return ip_set_type_register(&bitmap_port_type); -} - -static void __exit -bitmap_port_fini(void) -{ - ip_set_type_unregister(&bitmap_port_type); -} - -module_init(bitmap_port_init); -module_exit(bitmap_port_fini); diff --git a/extensions/ipset-6/ip_set_core.c b/extensions/ipset-6/ip_set_core.c deleted file mode 100644 index 9e446a9..0000000 --- a/extensions/ipset-6/ip_set_core.c +++ /dev/null @@ -1,1782 +0,0 @@ -/* Copyright (C) 2000-2002 Joakim Axelsson - * Patrick Schaaf - * Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module for IP set management */ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef IPSET_IN_KERNEL_TREE -#include -#endif -#include - -#include -#include -#include -#include "ip_set.h" -#include -#define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN) - -struct genlmsg_buf; - -static LIST_HEAD(ip_set_type_list); /* all registered set types */ -static DEFINE_MUTEX(ip_set_type_mutex); /* protects ip_set_type_list */ -static DEFINE_RWLOCK(ip_set_ref_lock); /* protects the set refs */ - -static struct ip_set **ip_set_list; /* all individual sets */ -static ip_set_id_t ip_set_max = LCONFIG_IP_SET_MAX; /* max number of sets */ - -#define STREQ(a, b) (strncmp(a, b, IPSET_MAXNAMELEN) == 0) - -static unsigned int max_sets; - -module_param(max_sets, int, 0600); -MODULE_PARM_DESC(max_sets, "maximal number of sets"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("core IP set support"); - -static struct genl_family ip_set_netlink_subsys; - -/* - * The set types are implemented in modules and registered set types - * can be found in ip_set_type_list. Adding/deleting types is - * serialized by ip_set_type_mutex. - */ - -static inline void -ip_set_type_lock(void) -{ - mutex_lock(&ip_set_type_mutex); -} - -static inline void -ip_set_type_unlock(void) -{ - mutex_unlock(&ip_set_type_mutex); -} - -/* Register and deregister settype */ - -static struct ip_set_type * -find_set_type(const char *name, u8 family, u8 revision) -{ - struct ip_set_type *type; - - list_for_each_entry_rcu(type, &ip_set_type_list, list) - if (STREQ(type->name, name) && - (type->family == family || type->family == NFPROTO_UNSPEC) && - revision >= type->revision_min && - revision <= type->revision_max) - return type; - return NULL; -} - -/* Unlock, try to load a set type module and lock again */ -static bool -load_settype(const char *name) -{ - genl_unlock(); - pr_debug("try to load ip_set_%s\n", name); - if (request_module("ip_set_%s", name) < 0) { - pr_warning("Can't find ip_set type %s\n", name); - genl_lock(); - return false; - } - genl_lock(); - return true; -} - -/* Find a set type and reference it */ -#define find_set_type_get(name, family, revision, found) \ - __find_set_type_get(name, family, revision, found, false) - -static int -__find_set_type_get(const char *name, u8 family, u8 revision, - struct ip_set_type **found, bool retry) -{ - struct ip_set_type *type; - int err; - - if (retry && !load_settype(name)) - return -IPSET_ERR_FIND_TYPE; - - rcu_read_lock(); - *found = find_set_type(name, family, revision); - if (*found) { - err = !try_module_get((*found)->me) ? -EFAULT : 0; - goto unlock; - } - /* Make sure the type is already loaded - * but we don't support the revision */ - list_for_each_entry_rcu(type, &ip_set_type_list, list) - if (STREQ(type->name, name)) { - err = -IPSET_ERR_FIND_TYPE; - goto unlock; - } - rcu_read_unlock(); - - return retry ? -IPSET_ERR_FIND_TYPE : - __find_set_type_get(name, family, revision, found, true); - -unlock: - rcu_read_unlock(); - return err; -} - -/* Find a given set type by name and family. - * If we succeeded, the supported minimal and maximum revisions are - * filled out. - */ -#define find_set_type_minmax(name, family, min, max) \ - __find_set_type_minmax(name, family, min, max, false) - -static int -__find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max, - bool retry) -{ - struct ip_set_type *type; - bool found = false; - - if (retry && !load_settype(name)) - return -IPSET_ERR_FIND_TYPE; - - *min = 255; *max = 0; - rcu_read_lock(); - list_for_each_entry_rcu(type, &ip_set_type_list, list) - if (STREQ(type->name, name) && - (type->family == family || type->family == NFPROTO_UNSPEC)) { - found = true; - if (type->revision_min < *min) - *min = type->revision_min; - if (type->revision_max > *max) - *max = type->revision_max; - } - rcu_read_unlock(); - if (found) - return 0; - - return retry ? -IPSET_ERR_FIND_TYPE : - __find_set_type_minmax(name, family, min, max, true); -} - -#define family_name(f) ((f) == NFPROTO_IPV4 ? "inet" : \ - (f) == NFPROTO_IPV6 ? "inet6" : "any") - -/* Register a set type structure. The type is identified by - * the unique triple of name, family and revision. - */ -int -ip_set_type_register(struct ip_set_type *type) -{ - int ret = 0; - - if (type->protocol != IPSET_PROTOCOL) { - pr_warning("ip_set type %s, family %s, revision %u:%u uses " - "wrong protocol version %u (want %u)\n", - type->name, family_name(type->family), - type->revision_min, type->revision_max, - type->protocol, IPSET_PROTOCOL); - return -EINVAL; - } - - ip_set_type_lock(); - if (find_set_type(type->name, type->family, type->revision_min)) { - /* Duplicate! */ - pr_warning("ip_set type %s, family %s with revision min %u " - "already registered!\n", type->name, - family_name(type->family), type->revision_min); - ret = -EINVAL; - goto unlock; - } - list_add_rcu(&type->list, &ip_set_type_list); - pr_debug("type %s, family %s, revision %u:%u registered.\n", - type->name, family_name(type->family), - type->revision_min, type->revision_max); -unlock: - ip_set_type_unlock(); - return ret; -} -EXPORT_SYMBOL_GPL(ip_set_type_register); - -/* Unregister a set type. There's a small race with ip_set_create */ -void -ip_set_type_unregister(struct ip_set_type *type) -{ - ip_set_type_lock(); - if (!find_set_type(type->name, type->family, type->revision_min)) { - pr_warning("ip_set type %s, family %s with revision min %u " - "not registered\n", type->name, - family_name(type->family), type->revision_min); - goto unlock; - } - list_del_rcu(&type->list); - pr_debug("type %s, family %s with revision min %u unregistered.\n", - type->name, family_name(type->family), type->revision_min); -unlock: - ip_set_type_unlock(); - - synchronize_rcu(); -} -EXPORT_SYMBOL_GPL(ip_set_type_unregister); - -/* Utility functions */ -void * -ip_set_alloc(size_t size) -{ - void *members = NULL; - - if (size < KMALLOC_MAX_SIZE) - members = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); - - if (members) { - pr_debug("%p: allocated with kmalloc\n", members); - return members; - } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) - members = __vmalloc(size, GFP_KERNEL | __GFP_ZERO | __GFP_HIGHMEM, - PAGE_KERNEL); -#else - members = vzalloc(size); -#endif - if (!members) - return NULL; - pr_debug("%p: allocated with vmalloc\n", members); - - return members; -} -EXPORT_SYMBOL_GPL(ip_set_alloc); - -void -ip_set_free(void *members) -{ - pr_debug("%p: free with %s\n", members, - is_vmalloc_addr(members) ? "vfree" : "kfree"); - if (is_vmalloc_addr(members)) - vfree(members); - else - kfree(members); -} -EXPORT_SYMBOL_GPL(ip_set_free); - -static inline bool -flag_nested(const struct nlattr *nla) -{ - return nla->nla_type & NLA_F_NESTED; -} - -static const struct nla_policy ipaddr_policy[IPSET_ATTR_IPADDR_MAX + 1] = { - [IPSET_ATTR_IPADDR_IPV4] = { .type = NLA_U32 }, - [IPSET_ATTR_IPADDR_IPV6] = { .type = NLA_BINARY, - .len = sizeof(struct in6_addr) }, -}; - -int -ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr) -{ - struct nlattr *tb[IPSET_ATTR_IPADDR_MAX+1]; - - if (unlikely(!flag_nested(nla))) - return -IPSET_ERR_PROTOCOL; - if (nla_parse_nested(tb, IPSET_ATTR_IPADDR_MAX, nla, ipaddr_policy)) - return -IPSET_ERR_PROTOCOL; - if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV4))) - return -IPSET_ERR_PROTOCOL; - - *ipaddr = nla_get_be32(tb[IPSET_ATTR_IPADDR_IPV4]); - return 0; -} -EXPORT_SYMBOL_GPL(ip_set_get_ipaddr4); - -int -ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr) -{ - struct nlattr *tb[IPSET_ATTR_IPADDR_MAX+1]; - - if (unlikely(!flag_nested(nla))) - return -IPSET_ERR_PROTOCOL; - - if (nla_parse_nested(tb, IPSET_ATTR_IPADDR_MAX, nla, ipaddr_policy)) - return -IPSET_ERR_PROTOCOL; - if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV6))) - return -IPSET_ERR_PROTOCOL; - - memcpy(ipaddr, nla_data(tb[IPSET_ATTR_IPADDR_IPV6]), - sizeof(struct in6_addr)); - return 0; -} -EXPORT_SYMBOL_GPL(ip_set_get_ipaddr6); - -/* - * Creating/destroying/renaming/swapping affect the existence and - * the properties of a set. All of these can be executed from userspace - * only and serialized by the nfnl mutex indirectly from nfnetlink. - * - * Sets are identified by their index in ip_set_list and the index - * is used by the external references (set/SET netfilter modules). - * - * The set behind an index may change by swapping only, from userspace. - */ - -static inline void -__ip_set_get(ip_set_id_t index) -{ - write_lock_bh(&ip_set_ref_lock); - ip_set_list[index]->ref++; - write_unlock_bh(&ip_set_ref_lock); -} - -static inline void -__ip_set_put(ip_set_id_t index) -{ - write_lock_bh(&ip_set_ref_lock); - BUG_ON(ip_set_list[index]->ref == 0); - ip_set_list[index]->ref--; - write_unlock_bh(&ip_set_ref_lock); -} - -/* - * Add, del and test set entries from kernel. - * - * The set behind the index must exist and must be referenced - * so it can't be destroyed (or changed) under our foot. - */ - -int -ip_set_test(ip_set_id_t index, const struct sk_buff *skb, - const struct xt_action_param *par, - const struct ip_set_adt_opt *opt) -{ - struct ip_set *set = ip_set_list[index]; - int ret = 0; - - BUG_ON(set == NULL); - pr_debug("set %s, index %u\n", set->name, index); - - if (opt->dim < set->type->dimension || - !(opt->family == set->family || set->family == NFPROTO_UNSPEC)) - return 0; - - read_lock_bh(&set->lock); - ret = set->variant->kadt(set, skb, par, IPSET_TEST, opt); - read_unlock_bh(&set->lock); - - if (ret == -EAGAIN) { - /* Type requests element to be completed */ - pr_debug("element must be competed, ADD is triggered\n"); - write_lock_bh(&set->lock); - set->variant->kadt(set, skb, par, IPSET_ADD, opt); - write_unlock_bh(&set->lock); - ret = 1; - } - - /* Convert error codes to nomatch */ - return (ret < 0 ? 0 : ret); -} -EXPORT_SYMBOL_GPL(ip_set_test); - -int -ip_set_add(ip_set_id_t index, const struct sk_buff *skb, - const struct xt_action_param *par, - const struct ip_set_adt_opt *opt) -{ - struct ip_set *set = ip_set_list[index]; - int ret; - - BUG_ON(set == NULL); - pr_debug("set %s, index %u\n", set->name, index); - - if (opt->dim < set->type->dimension || - !(opt->family == set->family || set->family == NFPROTO_UNSPEC)) - return 0; - - write_lock_bh(&set->lock); - ret = set->variant->kadt(set, skb, par, IPSET_ADD, opt); - write_unlock_bh(&set->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(ip_set_add); - -int -ip_set_del(ip_set_id_t index, const struct sk_buff *skb, - const struct xt_action_param *par, - const struct ip_set_adt_opt *opt) -{ - struct ip_set *set = ip_set_list[index]; - int ret = 0; - - BUG_ON(set == NULL); - pr_debug("set %s, index %u\n", set->name, index); - - if (opt->dim < set->type->dimension || - !(opt->family == set->family || set->family == NFPROTO_UNSPEC)) - return 0; - - write_lock_bh(&set->lock); - ret = set->variant->kadt(set, skb, par, IPSET_DEL, opt); - write_unlock_bh(&set->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(ip_set_del); - -/* - * Find set by name, reference it once. The reference makes sure the - * thing pointed to, does not go away under our feet. - * - */ -ip_set_id_t -ip_set_get_byname(const char *name, struct ip_set **set) -{ - ip_set_id_t i, index = IPSET_INVALID_ID; - struct ip_set *s; - - for (i = 0; i < ip_set_max; i++) { - s = ip_set_list[i]; - if (s != NULL && STREQ(s->name, name)) { - __ip_set_get(i); - index = i; - *set = s; - } - } - - return index; -} -EXPORT_SYMBOL_GPL(ip_set_get_byname); - -/* - * If the given set pointer points to a valid set, decrement - * reference count by 1. The caller shall not assume the index - * to be valid, after calling this function. - * - */ -void -ip_set_put_byindex(ip_set_id_t index) -{ - if (ip_set_list[index] != NULL) - __ip_set_put(index); -} -EXPORT_SYMBOL_GPL(ip_set_put_byindex); - -/* - * Get the name of a set behind a set index. - * We assume the set is referenced, so it does exist and - * can't be destroyed. The set cannot be renamed due to - * the referencing either. - * - */ -const char * -ip_set_name_byindex(ip_set_id_t index) -{ - const struct ip_set *set = ip_set_list[index]; - - BUG_ON(set == NULL); - BUG_ON(set->ref == 0); - - /* Referenced, so it's safe */ - return set->name; -} -EXPORT_SYMBOL_GPL(ip_set_name_byindex); - -/* - * Routines to call by external subsystems, which do not - * call nfnl_lock for us. - */ - -/* - * Find set by name, reference it once. The reference makes sure the - * thing pointed to, does not go away under our feet. - * - * The nfnl mutex is used in the function. - */ -ip_set_id_t -ip_set_nfnl_get(const char *name) -{ - struct ip_set *s; - ip_set_id_t index; - - genl_lock(); - index = ip_set_get_byname(name, &s); - genl_unlock(); - - return index; -} -EXPORT_SYMBOL_GPL(ip_set_nfnl_get); - -/* - * Find set by index, reference it once. The reference makes sure the - * thing pointed to, does not go away under our feet. - * - * The nfnl mutex is used in the function. - */ -ip_set_id_t -ip_set_nfnl_get_byindex(ip_set_id_t index) -{ - if (index > ip_set_max) - return IPSET_INVALID_ID; - - genl_lock(); - if (ip_set_list[index]) - __ip_set_get(index); - else - index = IPSET_INVALID_ID; - genl_unlock(); - - return index; -} -EXPORT_SYMBOL_GPL(ip_set_nfnl_get_byindex); - -/* - * If the given set pointer points to a valid set, decrement - * reference count by 1. The caller shall not assume the index - * to be valid, after calling this function. - * - * The nfnl mutex is used in the function. - */ -void -ip_set_nfnl_put(ip_set_id_t index) -{ - genl_lock(); - ip_set_put_byindex(index); - genl_unlock(); -} -EXPORT_SYMBOL_GPL(ip_set_nfnl_put); - -/* - * Communication protocol with userspace over netlink. - * - * The commands are serialized by the nfnl mutex. - */ - -static inline bool -protocol_failed(struct nlattr *const *tb) -{ - return !tb[IPSET_ATTR_PROTOCOL] || - nla_get_u8(tb[IPSET_ATTR_PROTOCOL]) != IPSET_PROTOCOL; -} - -static inline u32 -flag_exist(const struct genlmsghdr *ghdr) -{ - return ghdr->reserved & NLM_F_EXCL ? 0 : IPSET_FLAG_EXIST; -} - -static struct genlmsg_buf * -start_msg(struct sk_buff *skb, u32 pid, u32 seq, unsigned int flags, - enum ipset_cmd cmd) -{ - struct genlmsg_buf *nlh; - - nlh = genlmsg_put(skb, pid, seq, &ip_set_netlink_subsys, flags, cmd); - if (nlh == NULL) - return NULL; - return nlh; -} - -/* Create a set */ - -static const struct nla_policy ip_set_create_policy[IPSET_ATTR_CMD_MAX + 1] = { - [IPSET_ATTR_PROTOCOL] = { .type = NLA_U8 }, - [IPSET_ATTR_SETNAME] = { .type = NLA_NUL_STRING, - .len = IPSET_MAXNAMELEN - 1 }, - [IPSET_ATTR_TYPENAME] = { .type = NLA_NUL_STRING, - .len = IPSET_MAXNAMELEN - 1}, - [IPSET_ATTR_REVISION] = { .type = NLA_U8 }, - [IPSET_ATTR_FAMILY] = { .type = NLA_U8 }, - [IPSET_ATTR_DATA] = { .type = NLA_NESTED }, -}; - -static ip_set_id_t -find_set_id(const char *name) -{ - ip_set_id_t i, index = IPSET_INVALID_ID; - const struct ip_set *set; - - for (i = 0; index == IPSET_INVALID_ID && i < ip_set_max; i++) { - set = ip_set_list[i]; - if (set != NULL && STREQ(set->name, name)) - index = i; - } - return index; -} - -static inline struct ip_set * -find_set(const char *name) -{ - ip_set_id_t index = find_set_id(name); - - return index == IPSET_INVALID_ID ? NULL : ip_set_list[index]; -} - -static int -find_free_id(const char *name, ip_set_id_t *index, struct ip_set **set) -{ - ip_set_id_t i; - - *index = IPSET_INVALID_ID; - for (i = 0; i < ip_set_max; i++) { - if (ip_set_list[i] == NULL) { - if (*index == IPSET_INVALID_ID) - *index = i; - } else if (STREQ(name, ip_set_list[i]->name)) { - /* Name clash */ - *set = ip_set_list[i]; - return -EEXIST; - } - } - if (*index == IPSET_INVALID_ID) - /* No free slot remained */ - return -IPSET_ERR_MAX_SETS; - return 0; -} - -static int -ip_set_create(struct sk_buff *skb, struct genl_info *info) -{ - struct nlattr *const *attr = info->attrs; - struct ip_set *set, *clash = NULL; - ip_set_id_t index = IPSET_INVALID_ID; - struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1] = {}; - const char *name, *typename; - u8 family, revision; - u32 flags = flag_exist(info->genlhdr); - int ret = 0; - - if (unlikely(protocol_failed(attr) || - attr[IPSET_ATTR_SETNAME] == NULL || - attr[IPSET_ATTR_TYPENAME] == NULL || - attr[IPSET_ATTR_REVISION] == NULL || - attr[IPSET_ATTR_FAMILY] == NULL || - (attr[IPSET_ATTR_DATA] != NULL && - !flag_nested(attr[IPSET_ATTR_DATA])))) - return -IPSET_ERR_PROTOCOL; - - name = nla_data(attr[IPSET_ATTR_SETNAME]); - typename = nla_data(attr[IPSET_ATTR_TYPENAME]); - family = nla_get_u8(attr[IPSET_ATTR_FAMILY]); - revision = nla_get_u8(attr[IPSET_ATTR_REVISION]); - pr_debug("setname: %s, typename: %s, family: %s, revision: %u\n", - name, typename, family_name(family), revision); - - /* - * First, and without any locks, allocate and initialize - * a normal base set structure. - */ - set = kzalloc(sizeof(struct ip_set), GFP_KERNEL); - if (!set) - return -ENOMEM; - rwlock_init(&set->lock); - strlcpy(set->name, name, IPSET_MAXNAMELEN); - set->family = family; - set->revision = revision; - - /* - * Next, check that we know the type, and take - * a reference on the type, to make sure it stays available - * while constructing our new set. - * - * After referencing the type, we try to create the type - * specific part of the set without holding any locks. - */ - ret = find_set_type_get(typename, family, revision, &(set->type)); - if (ret) - goto out; - - /* - * Without holding any locks, create private part. - */ - if (attr[IPSET_ATTR_DATA] && - nla_parse_nested(tb, IPSET_ATTR_CREATE_MAX, attr[IPSET_ATTR_DATA], - set->type->create_policy)) { - ret = -IPSET_ERR_PROTOCOL; - goto put_out; - } - - ret = set->type->create(set, tb, flags); - if (ret != 0) - goto put_out; - - /* BTW, ret==0 here. */ - - /* - * Here, we have a valid, constructed set and we are protected - * by the nfnl mutex. Find the first free index in ip_set_list - * and check clashing. - */ - if ((ret = find_free_id(set->name, &index, &clash)) != 0) { - /* If this is the same set and requested, ignore error */ - if (ret == -EEXIST && - (flags & IPSET_FLAG_EXIST) && - STREQ(set->type->name, clash->type->name) && - set->type->family == clash->type->family && - set->type->revision_min == clash->type->revision_min && - set->type->revision_max == clash->type->revision_max && - set->variant->same_set(set, clash)) - ret = 0; - goto cleanup; - } - - /* - * Finally! Add our shiny new set to the list, and be done. - */ - pr_debug("create: '%s' created with index %u!\n", set->name, index); - ip_set_list[index] = set; - - return ret; - -cleanup: - set->variant->destroy(set); -put_out: - module_put(set->type->me); -out: - kfree(set); - return ret; -} - -/* Destroy sets */ - -static const struct nla_policy -ip_set_setname_policy[IPSET_ATTR_CMD_MAX + 1] = { - [IPSET_ATTR_PROTOCOL] = { .type = NLA_U8 }, - [IPSET_ATTR_SETNAME] = { .type = NLA_NUL_STRING, - .len = IPSET_MAXNAMELEN - 1 }, -}; - -static void -ip_set_destroy_set(ip_set_id_t index) -{ - struct ip_set *set = ip_set_list[index]; - - pr_debug("set: %s\n", set->name); - ip_set_list[index] = NULL; - - /* Must call it without holding any lock */ - set->variant->destroy(set); - module_put(set->type->me); - kfree(set); -} - -static int -ip_set_destroy(struct sk_buff *skb, struct genl_info *info) -{ - struct nlattr *const *attr = info->attrs; - ip_set_id_t i; - int ret = 0; - - if (unlikely(protocol_failed(attr))) - return -IPSET_ERR_PROTOCOL; - - /* Commands are serialized and references are - * protected by the ip_set_ref_lock. - * External systems (i.e. xt_set) must call - * ip_set_put|get_nfnl_* functions, that way we - * can safely check references here. - * - * list:set timer can only decrement the reference - * counter, so if it's already zero, we can proceed - * without holding the lock. - */ - read_lock_bh(&ip_set_ref_lock); - if (!attr[IPSET_ATTR_SETNAME]) { - for (i = 0; i < ip_set_max; i++) { - if (ip_set_list[i] != NULL && ip_set_list[i]->ref) { - ret = -IPSET_ERR_BUSY; - goto out; - } - } - read_unlock_bh(&ip_set_ref_lock); - for (i = 0; i < ip_set_max; i++) { - if (ip_set_list[i] != NULL) - ip_set_destroy_set(i); - } - } else { - i = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME])); - if (i == IPSET_INVALID_ID) { - ret = -ENOENT; - goto out; - } else if (ip_set_list[i]->ref) { - ret = -IPSET_ERR_BUSY; - goto out; - } - read_unlock_bh(&ip_set_ref_lock); - - ip_set_destroy_set(i); - } - return 0; -out: - read_unlock_bh(&ip_set_ref_lock); - return ret; -} - -/* Flush sets */ - -static void -ip_set_flush_set(struct ip_set *set) -{ - pr_debug("set: %s\n", set->name); - - write_lock_bh(&set->lock); - set->variant->flush(set); - write_unlock_bh(&set->lock); -} - -static int -ip_set_flush(struct sk_buff *skb, struct genl_info *info) -{ - struct nlattr *const *attr = info->attrs; - ip_set_id_t i; - - if (unlikely(protocol_failed(attr))) - return -IPSET_ERR_PROTOCOL; - - if (!attr[IPSET_ATTR_SETNAME]) { - for (i = 0; i < ip_set_max; i++) - if (ip_set_list[i] != NULL) - ip_set_flush_set(ip_set_list[i]); - } else { - i = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME])); - if (i == IPSET_INVALID_ID) - return -ENOENT; - - ip_set_flush_set(ip_set_list[i]); - } - - return 0; -} - -/* Rename a set */ - -static const struct nla_policy -ip_set_setname2_policy[IPSET_ATTR_CMD_MAX + 1] = { - [IPSET_ATTR_PROTOCOL] = { .type = NLA_U8 }, - [IPSET_ATTR_SETNAME] = { .type = NLA_NUL_STRING, - .len = IPSET_MAXNAMELEN - 1 }, - [IPSET_ATTR_SETNAME2] = { .type = NLA_NUL_STRING, - .len = IPSET_MAXNAMELEN - 1 }, -}; - -static int -ip_set_rename(struct sk_buff *skb, struct genl_info *info) -{ - struct nlattr *const *attr = info->attrs; - struct ip_set *set; - const char *name2; - ip_set_id_t i; - int ret = 0; - - if (unlikely(protocol_failed(attr) || - attr[IPSET_ATTR_SETNAME] == NULL || - attr[IPSET_ATTR_SETNAME2] == NULL)) - return -IPSET_ERR_PROTOCOL; - - set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); - if (set == NULL) - return -ENOENT; - - read_lock_bh(&ip_set_ref_lock); - if (set->ref != 0) { - ret = -IPSET_ERR_REFERENCED; - goto out; - } - - name2 = nla_data(attr[IPSET_ATTR_SETNAME2]); - for (i = 0; i < ip_set_max; i++) { - if (ip_set_list[i] != NULL && - STREQ(ip_set_list[i]->name, name2)) { - ret = -IPSET_ERR_EXIST_SETNAME2; - goto out; - } - } - strncpy(set->name, name2, IPSET_MAXNAMELEN); - -out: - read_unlock_bh(&ip_set_ref_lock); - return ret; -} - -/* Swap two sets so that name/index points to the other. - * References and set names are also swapped. - * - * The commands are serialized by the nfnl mutex and references are - * protected by the ip_set_ref_lock. The kernel interfaces - * do not hold the mutex but the pointer settings are atomic - * so the ip_set_list always contains valid pointers to the sets. - */ - -static int -ip_set_swap(struct sk_buff *skb, struct genl_info *info) -{ - struct nlattr *const *attr = info->attrs; - struct ip_set *from, *to; - ip_set_id_t from_id, to_id; - char from_name[IPSET_MAXNAMELEN]; - - if (unlikely(protocol_failed(attr) || - attr[IPSET_ATTR_SETNAME] == NULL || - attr[IPSET_ATTR_SETNAME2] == NULL)) - return -IPSET_ERR_PROTOCOL; - - from_id = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME])); - if (from_id == IPSET_INVALID_ID) - return -ENOENT; - - to_id = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME2])); - if (to_id == IPSET_INVALID_ID) - return -IPSET_ERR_EXIST_SETNAME2; - - from = ip_set_list[from_id]; - to = ip_set_list[to_id]; - - /* Features must not change. - * Not an artifical restriction anymore, as we must prevent - * possible loops created by swapping in setlist type of sets. */ - if (!(from->type->features == to->type->features && - from->type->family == to->type->family)) - return -IPSET_ERR_TYPE_MISMATCH; - - strncpy(from_name, from->name, IPSET_MAXNAMELEN); - strncpy(from->name, to->name, IPSET_MAXNAMELEN); - strncpy(to->name, from_name, IPSET_MAXNAMELEN); - - write_lock_bh(&ip_set_ref_lock); - swap(from->ref, to->ref); - ip_set_list[from_id] = to; - ip_set_list[to_id] = from; - write_unlock_bh(&ip_set_ref_lock); - - return 0; -} - -/* List/save set data */ - -#define DUMP_INIT 0 -#define DUMP_ALL 1 -#define DUMP_ONE 2 -#define DUMP_LAST 3 - -#define DUMP_TYPE(arg) (((u32)(arg)) & 0x0000FFFF) -#define DUMP_FLAGS(arg) (((u32)(arg)) >> 16) - -static int -ip_set_dump_done(struct netlink_callback *cb) -{ - if (cb->args[2]) { - pr_debug("release set %s\n", ip_set_list[cb->args[1]]->name); - ip_set_put_byindex((ip_set_id_t) cb->args[1]); - } - return 0; -} - -static inline void -dump_attrs(struct genlmsg_buf *phdr) -{ - const struct nlattr *attr; - const struct nlmsghdr *nlh = - (const void *)phdr - GENL_HDRLEN - NLMSG_HDRLEN; - int rem; - - pr_debug("dump nlmsg\n"); - nlmsg_for_each_attr(attr, nlh, sizeof(struct genlmsghdr), rem) { - pr_debug("type: %u, len %u\n", nla_type(attr), attr->nla_len); - } -} - -static int -dump_init(struct netlink_callback *cb) -{ - struct nlmsghdr *nlh = nlmsg_hdr(cb->skb); - int min_len = NLMSG_SPACE(sizeof(struct genlmsghdr)); - struct nlattr *cda[IPSET_ATTR_CMD_MAX+1]; - struct nlattr *attr = (void *)nlh + min_len; - u32 dump_type; - ip_set_id_t index; - - /* Second pass, so parser can't fail */ - nla_parse(cda, IPSET_ATTR_CMD_MAX, - attr, nlh->nlmsg_len - min_len, ip_set_setname_policy); - - /* cb->args[0] : dump single set/all sets - * [1] : set index - * [..]: type specific - */ - - if (cda[IPSET_ATTR_SETNAME]) { - index = find_set_id(nla_data(cda[IPSET_ATTR_SETNAME])); - if (index == IPSET_INVALID_ID) - return -ENOENT; - - dump_type = DUMP_ONE; - cb->args[1] = index; - } else - dump_type = DUMP_ALL; - - if (cda[IPSET_ATTR_FLAGS]) { - u32 f = ip_set_get_h32(cda[IPSET_ATTR_FLAGS]); - dump_type |= (f << 16); - } - cb->args[0] = dump_type; - - return 0; -} - -static int -ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb) -{ - ip_set_id_t index = IPSET_INVALID_ID, max; - struct ip_set *set = NULL; - struct genlmsg_buf *nlh = NULL; - unsigned int flags = NETLINK_CB(cb->skb).pid ? NLM_F_MULTI : 0; - u32 dump_type, dump_flags; - int ret = 0; - - if (!cb->args[0]) { - ret = dump_init(cb); - if (ret < 0) { - struct nlmsghdr *nlh = nlmsg_hdr(cb->skb); - /* We have to create and send the error message - * manually :-( */ - if (nlh->nlmsg_flags & NLM_F_ACK) - netlink_ack(cb->skb, nlh, ret); - return ret; - } - } - - if (cb->args[1] >= ip_set_max) - goto out; - - dump_type = DUMP_TYPE(cb->args[0]); - dump_flags = DUMP_FLAGS(cb->args[0]); - max = dump_type == DUMP_ONE ? cb->args[1] + 1 : ip_set_max; -dump_last: - pr_debug("args[0]: %u %u args[1]: %ld\n", - dump_type, dump_flags, cb->args[1]); - for (; cb->args[1] < max; cb->args[1]++) { - index = (ip_set_id_t) cb->args[1]; - set = ip_set_list[index]; - if (set == NULL) { - if (dump_type == DUMP_ONE) { - ret = -ENOENT; - goto out; - } - continue; - } - /* When dumping all sets, we must dump "sorted" - * so that lists (unions of sets) are dumped last. - */ - if (dump_type != DUMP_ONE && - ((dump_type == DUMP_ALL) == - !!(set->type->features & IPSET_DUMP_LAST))) - continue; - pr_debug("List set: %s\n", set->name); - if (!cb->args[2]) { - /* Start listing: make sure set won't be destroyed */ - pr_debug("reference set\n"); - __ip_set_get(index); - } - nlh = start_msg(skb, NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, flags, - IPSET_CMD_LIST); - if (!nlh) { - ret = -EMSGSIZE; - goto release_refcount; - } - NLA_PUT_U8(skb, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL); - NLA_PUT_STRING(skb, IPSET_ATTR_SETNAME, set->name); - if (dump_flags & IPSET_FLAG_LIST_SETNAME) - goto next_set; - switch (cb->args[2]) { - case 0: - /* Core header data */ - NLA_PUT_STRING(skb, IPSET_ATTR_TYPENAME, - set->type->name); - NLA_PUT_U8(skb, IPSET_ATTR_FAMILY, - set->family); - NLA_PUT_U8(skb, IPSET_ATTR_REVISION, - set->revision); - ret = set->variant->head(set, skb); - if (ret < 0) - goto release_refcount; - if (dump_flags & IPSET_FLAG_LIST_HEADER) - goto next_set; - /* Fall through and add elements */ - default: - read_lock_bh(&set->lock); - ret = set->variant->list(set, skb, cb); - read_unlock_bh(&set->lock); - if (!cb->args[2]) - /* Set is done, proceed with next one */ - goto next_set; - goto release_refcount; - } - } - /* If we dump all sets, continue with dumping last ones */ - if (dump_type == DUMP_ALL) { - dump_type = DUMP_LAST; - cb->args[0] = dump_type | (dump_flags << 16); - cb->args[1] = 0; - goto dump_last; - } - goto out; - -nla_put_failure: - ret = -EFAULT; -next_set: - if (dump_type == DUMP_ONE) - cb->args[1] = IPSET_INVALID_ID; - else - cb->args[1]++; -release_refcount: - /* If there was an error or set is done, release set */ - if (ret || !cb->args[2]) { - pr_debug("release set %s\n", ip_set_list[index]->name); - ip_set_put_byindex(index); - cb->args[2] = 0; - } -out: - if (nlh) { - genlmsg_end(skb, nlh); - pr_debug("nlmsg_len: %u\n", skb->len); - dump_attrs(nlh); - } - - return ret < 0 ? ret : skb->len; -} - -static int -ip_set_dump(struct sk_buff *skb, struct genl_info *info) -{ - struct nlattr *const *attr = info->attrs; - struct nlmsghdr *nlh = info->nlhdr; - struct sock *ctnl = genl_info_net(info)->genl_sock; - int ret; - - if (unlikely(protocol_failed(attr))) - return -IPSET_ERR_PROTOCOL; - - genl_unlock(); - ret = netlink_dump_start(ctnl, skb, nlh, - ip_set_dump_start, -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0) - ip_set_dump_done); -#else - ip_set_dump_done, 0); -#endif - genl_lock(); - return ret; -} - -/* Add, del and test */ - -static const struct nla_policy ip_set_adt_policy[IPSET_ATTR_CMD_MAX + 1] = { - [IPSET_ATTR_PROTOCOL] = { .type = NLA_U8 }, - [IPSET_ATTR_SETNAME] = { .type = NLA_NUL_STRING, - .len = IPSET_MAXNAMELEN - 1 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, - [IPSET_ATTR_DATA] = { .type = NLA_NESTED }, - [IPSET_ATTR_ADT] = { .type = NLA_NESTED }, -}; - -static int -call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set, - struct nlattr *tb[], enum ipset_adt adt, - u32 flags, bool use_lineno) -{ - int ret; - u32 lineno = 0; - bool eexist = flags & IPSET_FLAG_EXIST, retried = false; - - do { - write_lock_bh(&set->lock); - ret = set->variant->uadt(set, tb, adt, &lineno, flags, retried); - write_unlock_bh(&set->lock); - retried = true; - } while (ret == -EAGAIN && - set->variant->resize && - (ret = set->variant->resize(set, retried)) == 0); - - if (!ret || (ret == -IPSET_ERR_EXIST && eexist)) - return 0; - if (lineno && use_lineno) { - /* Error in restore/batch mode: send back lineno */ - struct nlmsghdr *rep, *nlh = nlmsg_hdr(skb); - struct sk_buff *skb2; - struct nlmsgerr *errmsg; - size_t payload = sizeof(*errmsg) + nlmsg_len(nlh); - int min_len = NLMSG_SPACE(sizeof(struct genlmsghdr)); - struct nlattr *cda[IPSET_ATTR_CMD_MAX+1]; - struct nlattr *cmdattr; - u32 *errline; - - skb2 = nlmsg_new(payload, GFP_KERNEL); - if (skb2 == NULL) - return -ENOMEM; - rep = __nlmsg_put(skb2, NETLINK_CB(skb).pid, - nlh->nlmsg_seq, NLMSG_ERROR, payload, 0); - errmsg = nlmsg_data(rep); - errmsg->error = ret; - memcpy(&errmsg->msg, nlh, nlh->nlmsg_len); - cmdattr = (void *)&errmsg->msg + min_len; - - nla_parse(cda, IPSET_ATTR_CMD_MAX, - cmdattr, nlh->nlmsg_len - min_len, - ip_set_adt_policy); - - errline = nla_data(cda[IPSET_ATTR_LINENO]); - - *errline = lineno; - - netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT); - /* Signal netlink not to send its ACK/errmsg. */ - return -EINTR; - } - - return ret; -} - -static int -ip_set_uadd(struct sk_buff *skb, struct genl_info *info) -{ - struct nlattr *const *attr = info->attrs; - struct sock *ctnl = genl_info_net(info)->genl_sock; - - struct ip_set *set; - struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {}; - const struct nlattr *nla; - u32 flags = flag_exist(info->genlhdr); - bool use_lineno; - int ret = 0; - - if (unlikely(protocol_failed(attr) || - attr[IPSET_ATTR_SETNAME] == NULL || - !((attr[IPSET_ATTR_DATA] != NULL) ^ - (attr[IPSET_ATTR_ADT] != NULL)) || - (attr[IPSET_ATTR_DATA] != NULL && - !flag_nested(attr[IPSET_ATTR_DATA])) || - (attr[IPSET_ATTR_ADT] != NULL && - (!flag_nested(attr[IPSET_ATTR_ADT]) || - attr[IPSET_ATTR_LINENO] == NULL)))) - return -IPSET_ERR_PROTOCOL; - - set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); - if (set == NULL) - return -ENOENT; - - use_lineno = !!attr[IPSET_ATTR_LINENO]; - if (attr[IPSET_ATTR_DATA]) { - if (nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, - attr[IPSET_ATTR_DATA], - set->type->adt_policy)) - return -IPSET_ERR_PROTOCOL; - ret = call_ad(ctnl, skb, set, tb, IPSET_ADD, flags, - use_lineno); - } else { - int nla_rem; - - nla_for_each_nested(nla, attr[IPSET_ATTR_ADT], nla_rem) { - memset(tb, 0, sizeof(tb)); - if (nla_type(nla) != IPSET_ATTR_DATA || - !flag_nested(nla) || - nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, nla, - set->type->adt_policy)) - return -IPSET_ERR_PROTOCOL; - ret = call_ad(ctnl, skb, set, tb, IPSET_ADD, - flags, use_lineno); - if (ret < 0) - return ret; - } - } - return ret; -} - -static int -ip_set_udel(struct sk_buff *skb, struct genl_info *info) -{ - struct nlattr *const *attr = info->attrs; - struct sock *ctnl = genl_info_net(info)->genl_sock; - - struct ip_set *set; - struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {}; - const struct nlattr *nla; - u32 flags = flag_exist(info->genlhdr); - bool use_lineno; - int ret = 0; - - if (unlikely(protocol_failed(attr) || - attr[IPSET_ATTR_SETNAME] == NULL || - !((attr[IPSET_ATTR_DATA] != NULL) ^ - (attr[IPSET_ATTR_ADT] != NULL)) || - (attr[IPSET_ATTR_DATA] != NULL && - !flag_nested(attr[IPSET_ATTR_DATA])) || - (attr[IPSET_ATTR_ADT] != NULL && - (!flag_nested(attr[IPSET_ATTR_ADT]) || - attr[IPSET_ATTR_LINENO] == NULL)))) - return -IPSET_ERR_PROTOCOL; - - set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); - if (set == NULL) - return -ENOENT; - - use_lineno = !!attr[IPSET_ATTR_LINENO]; - if (attr[IPSET_ATTR_DATA]) { - if (nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, - attr[IPSET_ATTR_DATA], - set->type->adt_policy)) - return -IPSET_ERR_PROTOCOL; - ret = call_ad(ctnl, skb, set, tb, IPSET_DEL, flags, - use_lineno); - } else { - int nla_rem; - - nla_for_each_nested(nla, attr[IPSET_ATTR_ADT], nla_rem) { - memset(tb, 0, sizeof(*tb)); - if (nla_type(nla) != IPSET_ATTR_DATA || - !flag_nested(nla) || - nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, nla, - set->type->adt_policy)) - return -IPSET_ERR_PROTOCOL; - ret = call_ad(ctnl, skb, set, tb, IPSET_DEL, - flags, use_lineno); - if (ret < 0) - return ret; - } - } - return ret; -} - -static int -ip_set_utest(struct sk_buff *skb, struct genl_info *info) -{ - struct nlattr *const *attr = info->attrs; - - struct ip_set *set; - struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {}; - int ret = 0; - - if (unlikely(protocol_failed(attr) || - attr[IPSET_ATTR_SETNAME] == NULL || - attr[IPSET_ATTR_DATA] == NULL || - !flag_nested(attr[IPSET_ATTR_DATA]))) - return -IPSET_ERR_PROTOCOL; - - set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); - if (set == NULL) - return -ENOENT; - - if (nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, attr[IPSET_ATTR_DATA], - set->type->adt_policy)) - return -IPSET_ERR_PROTOCOL; - - read_lock_bh(&set->lock); - ret = set->variant->uadt(set, tb, IPSET_TEST, NULL, 0, 0); - read_unlock_bh(&set->lock); - /* Userspace can't trigger element to be re-added */ - if (ret == -EAGAIN) - ret = 1; - - return ret < 0 ? ret : ret > 0 ? 0 : -IPSET_ERR_EXIST; -} - -/* Get headed data of a set */ - -static int -ip_set_header(struct sk_buff *skb, struct genl_info *info) -{ - const struct ip_set *set; - struct nlattr *const *attr = info->attrs; - const struct nlmsghdr *nlh = info->nlhdr; - struct sk_buff *skb2; - struct genlmsg_buf *nlh2; - ip_set_id_t index; - int ret = 0; - - if (unlikely(protocol_failed(attr) || - attr[IPSET_ATTR_SETNAME] == NULL)) - return -IPSET_ERR_PROTOCOL; - - index = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME])); - if (index == IPSET_INVALID_ID) - return -ENOENT; - set = ip_set_list[index]; - - skb2 = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (skb2 == NULL) - return -ENOMEM; - - nlh2 = start_msg(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, - IPSET_CMD_HEADER); - if (!nlh2) - goto nlmsg_failure; - NLA_PUT_U8(skb2, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL); - NLA_PUT_STRING(skb2, IPSET_ATTR_SETNAME, set->name); - NLA_PUT_STRING(skb2, IPSET_ATTR_TYPENAME, set->type->name); - NLA_PUT_U8(skb2, IPSET_ATTR_FAMILY, set->family); - NLA_PUT_U8(skb2, IPSET_ATTR_REVISION, set->revision); - genlmsg_end(skb2, nlh2); - - ret = genlmsg_unicast(genl_info_net(info), skb2, NETLINK_CB(skb).pid); - if (ret < 0) - return ret; - - return 0; - -nla_put_failure: - genlmsg_cancel(skb2, nlh2); -nlmsg_failure: - kfree_skb(skb2); - return -EMSGSIZE; -} - -/* Get type data */ - -static const struct nla_policy ip_set_type_policy[IPSET_ATTR_CMD_MAX + 1] = { - [IPSET_ATTR_PROTOCOL] = { .type = NLA_U8 }, - [IPSET_ATTR_TYPENAME] = { .type = NLA_NUL_STRING, - .len = IPSET_MAXNAMELEN - 1 }, - [IPSET_ATTR_FAMILY] = { .type = NLA_U8 }, -}; - -static int -ip_set_type(struct sk_buff *skb, struct genl_info *info) -{ - struct nlattr *const *attr = info->attrs; - const struct nlmsghdr *nlh = info->nlhdr; - - struct sk_buff *skb2; - struct genlmsg_buf *nlh2; - u8 family, min, max; - const char *typename; - int ret = 0; - - if (unlikely(protocol_failed(attr) || - attr[IPSET_ATTR_TYPENAME] == NULL || - attr[IPSET_ATTR_FAMILY] == NULL)) - return -IPSET_ERR_PROTOCOL; - - family = nla_get_u8(attr[IPSET_ATTR_FAMILY]); - typename = nla_data(attr[IPSET_ATTR_TYPENAME]); - ret = find_set_type_minmax(typename, family, &min, &max); - if (ret) - return ret; - - skb2 = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (skb2 == NULL) - return -ENOMEM; - - nlh2 = start_msg(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, - IPSET_CMD_TYPE); - if (!nlh2) - goto nlmsg_failure; - NLA_PUT_U8(skb2, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL); - NLA_PUT_STRING(skb2, IPSET_ATTR_TYPENAME, typename); - NLA_PUT_U8(skb2, IPSET_ATTR_FAMILY, family); - NLA_PUT_U8(skb2, IPSET_ATTR_REVISION, max); - NLA_PUT_U8(skb2, IPSET_ATTR_REVISION_MIN, min); - genlmsg_end(skb2, nlh2); - - pr_debug("Send TYPE, nlmsg_len: %u\n", skb2->len); - ret = genlmsg_unicast(genl_info_net(info), skb2, NETLINK_CB(skb).pid); - if (ret < 0) - return ret; - - return 0; - -nla_put_failure: - genlmsg_cancel(skb2, nlh2); -nlmsg_failure: - kfree_skb(skb2); - return -EMSGSIZE; -} - -/* Get protocol version */ - -static const struct nla_policy -ip_set_protocol_policy[IPSET_ATTR_CMD_MAX + 1] = { - [IPSET_ATTR_PROTOCOL] = { .type = NLA_U8 }, -}; - -static int -ip_set_protocol(struct sk_buff *skb, struct genl_info *info) -{ - struct nlattr *const *attr = info->attrs; - const struct nlmsghdr *nlh = info->nlhdr; - - struct sk_buff *skb2; - struct genlmsg_buf *nlh2; - int ret = 0; - - if (unlikely(attr[IPSET_ATTR_PROTOCOL] == NULL)) - return -IPSET_ERR_PROTOCOL; - - skb2 = genlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (skb2 == NULL) - return -ENOMEM; - - nlh2 = start_msg(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, - IPSET_CMD_PROTOCOL); - if (!nlh2) - goto nlmsg_failure; - NLA_PUT_U8(skb2, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL); - genlmsg_end(skb2, nlh2); - - ret = genlmsg_unicast(genl_info_net(info), skb2, NETLINK_CB(skb).pid); - if (ret < 0) - return ret; - - return 0; - -nla_put_failure: - genlmsg_cancel(skb2, nlh2); -nlmsg_failure: - kfree_skb(skb2); - return -EMSGSIZE; -} - -static struct genl_ops ip_set_netlink_subsys_cb[] __read_mostly = { - { - .cmd = IPSET_CMD_CREATE, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_create, - .policy = ip_set_create_policy, - }, - { - .cmd = IPSET_CMD_DESTROY, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_destroy, - .policy = ip_set_setname_policy, - }, - { - .cmd = IPSET_CMD_FLUSH, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_flush, - .policy = ip_set_setname_policy, - }, - { - .cmd = IPSET_CMD_RENAME, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_rename, - .policy = ip_set_setname2_policy, - }, - { - .cmd = IPSET_CMD_SWAP, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_swap, - .policy = ip_set_setname2_policy, - }, - { - .cmd = IPSET_CMD_LIST, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_dump, - .policy = ip_set_setname_policy, - }, - { - .cmd = IPSET_CMD_SAVE, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_dump, - .policy = ip_set_setname_policy, - }, - { - .cmd = IPSET_CMD_ADD, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_uadd, - .policy = ip_set_adt_policy, - }, - { - .cmd = IPSET_CMD_DEL, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_udel, - .policy = ip_set_adt_policy, - }, - { - .cmd = IPSET_CMD_TEST, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_utest, - .policy = ip_set_adt_policy, - }, - { - .cmd = IPSET_CMD_HEADER, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_header, - .policy = ip_set_setname_policy, - }, - { - .cmd = IPSET_CMD_TYPE, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_type, - .policy = ip_set_type_policy, - }, - { - .cmd = IPSET_CMD_PROTOCOL, - .flags = GENL_ADMIN_PERM, - .doit = ip_set_protocol, - .policy = ip_set_protocol_policy, - }, -}; - -static struct genl_family ip_set_netlink_subsys __read_mostly = { - .name = "ip_set", - .id = GENL_ID_GENERATE, - .hdrsize = 0, - .version = 5, - .maxattr = IPSET_ATTR_CMD_MAX, -}; - -/* Interface to iptables/ip6tables */ - -static int -ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len) -{ - unsigned *op; - void *data; - int copylen = *len, ret = 0; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (optval != SO_IP_SET) - return -EBADF; - if (*len < sizeof(unsigned)) - return -EINVAL; - - data = vmalloc(*len); - if (!data) - return -ENOMEM; - if (copy_from_user(data, user, *len) != 0) { - ret = -EFAULT; - goto done; - } - op = (unsigned *) data; - - if (*op < IP_SET_OP_VERSION) { - /* Check the version at the beginning of operations */ - struct ip_set_req_version *req_version = data; - if (req_version->version != IPSET_PROTOCOL) { - ret = -EPROTO; - goto done; - } - } - - switch (*op) { - case IP_SET_OP_VERSION: { - struct ip_set_req_version *req_version = data; - - if (*len != sizeof(struct ip_set_req_version)) { - ret = -EINVAL; - goto done; - } - - req_version->version = IPSET_PROTOCOL; - ret = copy_to_user(user, req_version, - sizeof(struct ip_set_req_version)); - goto done; - } - case IP_SET_OP_GET_BYNAME: { - struct ip_set_req_get_set *req_get = data; - - if (*len != sizeof(struct ip_set_req_get_set)) { - ret = -EINVAL; - goto done; - } - req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0'; - genl_lock(); - req_get->set.index = find_set_id(req_get->set.name); - genl_unlock(); - goto copy; - } - case IP_SET_OP_GET_BYINDEX: { - struct ip_set_req_get_set *req_get = data; - - if (*len != sizeof(struct ip_set_req_get_set) || - req_get->set.index >= ip_set_max) { - ret = -EINVAL; - goto done; - } - genl_lock(); - strncpy(req_get->set.name, - ip_set_list[req_get->set.index] - ? ip_set_list[req_get->set.index]->name : "", - IPSET_MAXNAMELEN); - genl_unlock(); - goto copy; - } - default: - ret = -EBADMSG; - goto done; - } /* end of switch(op) */ - -copy: - ret = copy_to_user(user, data, copylen); - -done: - vfree(data); - if (ret > 0) - ret = 0; - return ret; -} - -static struct nf_sockopt_ops so_set __read_mostly = { - .pf = PF_INET, - .get_optmin = SO_IP_SET, - .get_optmax = SO_IP_SET + 1, - .get = &ip_set_sockfn_get, - .owner = THIS_MODULE, -}; - -static int __init -ip_set_init(void) -{ - int ret; - - if (max_sets) - ip_set_max = max_sets; - if (ip_set_max >= IPSET_INVALID_ID) - ip_set_max = IPSET_INVALID_ID - 1; - - ip_set_list = kzalloc(sizeof(struct ip_set *) * ip_set_max, - GFP_KERNEL); - if (!ip_set_list) - return -ENOMEM; - - ret = genl_register_family_with_ops(&ip_set_netlink_subsys, - ip_set_netlink_subsys_cb, ARRAY_SIZE(ip_set_netlink_subsys_cb)); - if (ret != 0) { - pr_err("ip_set: cannot register with genetlink."); - kfree(ip_set_list); - return ret; - } - ret = nf_register_sockopt(&so_set); - if (ret != 0) { - pr_err("SO_SET registry failed: %d\n", ret); - genl_unregister_family(&ip_set_netlink_subsys); - kfree(ip_set_list); - return ret; - } - - pr_notice("ip_set: protocol %u\n", IPSET_PROTOCOL); - return 0; -} - -static void __exit -ip_set_fini(void) -{ - /* There can't be any existing set */ - nf_unregister_sockopt(&so_set); - genl_unregister_family(&ip_set_netlink_subsys); - kfree(ip_set_list); - pr_debug("these are the famous last words\n"); -} - -module_init(ip_set_init); -module_exit(ip_set_fini); diff --git a/extensions/ipset-6/ip_set_getport.c b/extensions/ipset-6/ip_set_getport.c deleted file mode 100644 index ae80896..0000000 --- a/extensions/ipset-6/ip_set_getport.c +++ /dev/null @@ -1,161 +0,0 @@ -/* Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Get Layer-4 data from the packets */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ip_set_getport.h" - -/* We must handle non-linear skbs */ -static bool -get_port(const struct sk_buff *skb, int protocol, unsigned int protooff, - bool src, __be16 *port, u8 *proto) -{ - switch (protocol) { - case IPPROTO_TCP: { - struct tcphdr _tcph; - const struct tcphdr *th; - - th = skb_header_pointer(skb, protooff, sizeof(_tcph), &_tcph); - if (th == NULL) - /* No choice either */ - return false; - - *port = src ? th->source : th->dest; - break; - } - case IPPROTO_SCTP: { - sctp_sctphdr_t _sh; - const sctp_sctphdr_t *sh; - - sh = skb_header_pointer(skb, protooff, sizeof(_sh), &_sh); - if (sh == NULL) - /* No choice either */ - return false; - - *port = src ? sh->source : sh->dest; - break; - } - case IPPROTO_UDP: - case IPPROTO_UDPLITE: { - struct udphdr _udph; - const struct udphdr *uh; - - uh = skb_header_pointer(skb, protooff, sizeof(_udph), &_udph); - if (uh == NULL) - /* No choice either */ - return false; - - *port = src ? uh->source : uh->dest; - break; - } - case IPPROTO_ICMP: { - struct icmphdr _ich; - const struct icmphdr *ic; - - ic = skb_header_pointer(skb, protooff, sizeof(_ich), &_ich); - if (ic == NULL) - return false; - - *port = (__force __be16)htons((ic->type << 8) | ic->code); - break; - } - case IPPROTO_ICMPV6: { - struct icmp6hdr _ich; - const struct icmp6hdr *ic; - - ic = skb_header_pointer(skb, protooff, sizeof(_ich), &_ich); - if (ic == NULL) - return false; - - *port = (__force __be16) - htons((ic->icmp6_type << 8) | ic->icmp6_code); - break; - } - default: - break; - } - *proto = protocol; - - return true; -} - -bool -ip_set_get_ip4_port(const struct sk_buff *skb, bool src, - __be16 *port, u8 *proto) -{ - const struct iphdr *iph = ip_hdr(skb); - unsigned int protooff = ip_hdrlen(skb); - int protocol = iph->protocol; - - /* See comments at tcp_match in ip_tables.c */ - if (protocol <= 0 || (ntohs(iph->frag_off) & IP_OFFSET)) - return false; - - return get_port(skb, protocol, protooff, src, port, proto); -} -EXPORT_SYMBOL_GPL(ip_set_get_ip4_port); - -#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) -bool -ip_set_get_ip6_port(const struct sk_buff *skb, bool src, - __be16 *port, u8 *proto) -{ - int protoff; - u8 nexthdr; - __be16 frag_off; - - nexthdr = ipv6_hdr(skb)->nexthdr; -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) - protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr); -#else - protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, &frag_off); -#endif - if (protoff < 0) - return false; - - return get_port(skb, nexthdr, protoff, src, port, proto); -} -EXPORT_SYMBOL_GPL(ip_set_get_ip6_port); -#endif - -bool -ip_set_get_ip_port(const struct sk_buff *skb, u8 pf, bool src, __be16 *port) -{ - bool ret; - u8 proto; - - switch (pf) { - case NFPROTO_IPV4: - ret = ip_set_get_ip4_port(skb, src, port, &proto); - break; - case NFPROTO_IPV6: - ret = ip_set_get_ip6_port(skb, src, port, &proto); - break; - default: - return false; - } - if (!ret) - return ret; - switch (proto) { - case IPPROTO_TCP: - case IPPROTO_UDP: - return true; - default: - return false; - } -} -EXPORT_SYMBOL_GPL(ip_set_get_ip_port); diff --git a/extensions/ipset-6/ip_set_getport.h b/extensions/ipset-6/ip_set_getport.h deleted file mode 100644 index 90d0930..0000000 --- a/extensions/ipset-6/ip_set_getport.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _IP_SET_GETPORT_H -#define _IP_SET_GETPORT_H - -extern bool ip_set_get_ip4_port(const struct sk_buff *skb, bool src, - __be16 *port, u8 *proto); - -#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) -extern bool ip_set_get_ip6_port(const struct sk_buff *skb, bool src, - __be16 *port, u8 *proto); -#else -static inline bool ip_set_get_ip6_port(const struct sk_buff *skb, bool src, - __be16 *port, u8 *proto) -{ - return false; -} -#endif - -extern bool ip_set_get_ip_port(const struct sk_buff *skb, u8 pf, bool src, - __be16 *port); - -static inline bool ip_set_proto_with_ports(u8 proto) -{ - switch (proto) { - case IPPROTO_TCP: - case IPPROTO_SCTP: - case IPPROTO_UDP: - case IPPROTO_UDPLITE: - return true; - } - return false; -} - -#endif /*_IP_SET_GETPORT_H*/ diff --git a/extensions/ipset-6/ip_set_hash.h b/extensions/ipset-6/ip_set_hash.h deleted file mode 100644 index e2a9fae..0000000 --- a/extensions/ipset-6/ip_set_hash.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __IP_SET_HASH_H -#define __IP_SET_HASH_H - -/* Hash type specific error codes */ -enum { - /* Hash is full */ - IPSET_ERR_HASH_FULL = IPSET_ERR_TYPE_SPECIFIC, - /* Null-valued element */ - IPSET_ERR_HASH_ELEM, - /* Invalid protocol */ - IPSET_ERR_INVALID_PROTO, - /* Protocol missing but must be specified */ - IPSET_ERR_MISSING_PROTO, - /* Range not supported */ - IPSET_ERR_HASH_RANGE_UNSUPPORTED, - /* Invalid range */ - IPSET_ERR_HASH_RANGE, -}; - -#ifdef __KERNEL__ - -#define IPSET_DEFAULT_HASHSIZE 1024 -#define IPSET_MIMINAL_HASHSIZE 64 -#define IPSET_DEFAULT_MAXELEM 65536 -#define IPSET_DEFAULT_PROBES 4 -#define IPSET_DEFAULT_RESIZE 100 - -#endif /* __KERNEL__ */ - -#endif /* __IP_SET_HASH_H */ diff --git a/extensions/ipset-6/ip_set_hash_ip.c b/extensions/ipset-6/ip_set_hash_ip.c deleted file mode 100644 index 91fd50f..0000000 --- a/extensions/ipset-6/ip_set_hash_ip.c +++ /dev/null @@ -1,481 +0,0 @@ -/* Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module implementing an IP set type: the hash:ip type */ - -#include "jhash.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "pfxlen.h" -#include "ip_set.h" -#include "ip_set_timeout.h" -#include "ip_set_hash.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("hash:ip type of IP sets"); -MODULE_ALIAS("ip_set_hash:ip"); - -/* Type specific function prefix */ -#define TYPE hash_ip - -static bool -hash_ip_same_set(const struct ip_set *a, const struct ip_set *b); - -#define hash_ip4_same_set hash_ip_same_set -#define hash_ip6_same_set hash_ip_same_set - -/* The type variant functions: IPv4 */ - -/* Member elements without timeout */ -struct hash_ip4_elem { - __be32 ip; -}; - -/* Member elements with timeout support */ -struct hash_ip4_telem { - __be32 ip; - unsigned long timeout; -}; - -static inline bool -hash_ip4_data_equal(const struct hash_ip4_elem *ip1, - const struct hash_ip4_elem *ip2, - u32 *multi) -{ - return ip1->ip == ip2->ip; -} - -static inline bool -hash_ip4_data_isnull(const struct hash_ip4_elem *elem) -{ - return elem->ip == 0; -} - -static inline void -hash_ip4_data_copy(struct hash_ip4_elem *dst, const struct hash_ip4_elem *src) -{ - dst->ip = src->ip; -} - -/* Zero valued IP addresses cannot be stored */ -static inline void -hash_ip4_data_zero_out(struct hash_ip4_elem *elem) -{ - elem->ip = 0; -} - -static inline bool -hash_ip4_data_list(struct sk_buff *skb, const struct hash_ip4_elem *data) -{ - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_ip4_data_tlist(struct sk_buff *skb, const struct hash_ip4_elem *data) -{ - const struct hash_ip4_telem *tdata = - (const struct hash_ip4_telem *)data; - - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(tdata->timeout))); - - return 0; - -nla_put_failure: - return 1; -} - -#define IP_SET_HASH_WITH_NETMASK -#define PF 4 -#define HOST_MASK 32 -#include "ip_set_ahash.h" - -static inline void -hash_ip4_data_next(struct ip_set_hash *h, const struct hash_ip4_elem *d) -{ - h->next.ip = ntohl(d->ip); -} - -static int -hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - __be32 ip; - - ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip); - ip &= ip_set_netmask(h->netmask); - if (ip == 0) - return -EINVAL; - - return adtfn(set, &ip, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - u32 ip, ip_to, hosts, timeout = h->timeout; - __be32 nip; - int ret = 0; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); - if (ret) - return ret; - - ip &= ip_set_hostmask(h->netmask); - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - if (adt == IPSET_TEST) { - nip = htonl(ip); - if (nip == 0) - return -IPSET_ERR_HASH_ELEM; - return adtfn(set, &nip, timeout, flags); - } - - if (tb[IPSET_ATTR_IP_TO]) { - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); - if (ret) - return ret; - if (ip > ip_to) - swap(ip, ip_to); - } else if (tb[IPSET_ATTR_CIDR]) { - u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - - if (cidr > 32) - return -IPSET_ERR_INVALID_CIDR; - ip_set_mask_from_to(ip, ip_to, cidr); - } else - ip_to = ip; - - hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1); - - if (retried) - ip = h->next.ip; - for (; !before(ip_to, ip); ip += hosts) { - nip = htonl(ip); - if (nip == 0) - return -IPSET_ERR_HASH_ELEM; - ret = adtfn(set, &nip, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - } - return ret; -} - -static bool -hash_ip_same_set(const struct ip_set *a, const struct ip_set *b) -{ - const struct ip_set_hash *x = a->data; - const struct ip_set_hash *y = b->data; - - /* Resizing changes htable_bits, so we ignore it */ - return x->maxelem == y->maxelem && - x->timeout == y->timeout && - x->netmask == y->netmask; -} - -/* The type variant functions: IPv6 */ - -struct hash_ip6_elem { - union nf_inet_addr ip; -}; - -struct hash_ip6_telem { - union nf_inet_addr ip; - unsigned long timeout; -}; - -static inline bool -hash_ip6_data_equal(const struct hash_ip6_elem *ip1, - const struct hash_ip6_elem *ip2, - u32 *multi) -{ - return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0; -} - -static inline bool -hash_ip6_data_isnull(const struct hash_ip6_elem *elem) -{ - return ipv6_addr_any(&elem->ip.in6); -} - -static inline void -hash_ip6_data_copy(struct hash_ip6_elem *dst, const struct hash_ip6_elem *src) -{ - dst->ip.in6 = src->ip.in6; -} - -static inline void -hash_ip6_data_zero_out(struct hash_ip6_elem *elem) -{ - ipv6_addr_set(&elem->ip.in6, 0, 0, 0, 0); -} - -static inline void -ip6_netmask(union nf_inet_addr *ip, u8 prefix) -{ - ip->ip6[0] &= ip_set_netmask6(prefix)[0]; - ip->ip6[1] &= ip_set_netmask6(prefix)[1]; - ip->ip6[2] &= ip_set_netmask6(prefix)[2]; - ip->ip6[3] &= ip_set_netmask6(prefix)[3]; -} - -static bool -hash_ip6_data_list(struct sk_buff *skb, const struct hash_ip6_elem *data) -{ - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_ip6_data_tlist(struct sk_buff *skb, const struct hash_ip6_elem *data) -{ - const struct hash_ip6_telem *e = - (const struct hash_ip6_telem *)data; - - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(e->timeout))); - return 0; - -nla_put_failure: - return 1; -} - -#undef PF -#undef HOST_MASK - -#define PF 6 -#define HOST_MASK 128 -#include "ip_set_ahash.h" - -static inline void -hash_ip6_data_next(struct ip_set_hash *h, const struct hash_ip6_elem *d) -{ -} - -static int -hash_ip6_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - union nf_inet_addr ip; - - ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip.in6); - ip6_netmask(&ip, h->netmask); - if (ipv6_addr_any(&ip.in6)) - return -EINVAL; - - return adtfn(set, &ip, opt_timeout(opt, h), opt->cmdflags); -} - -static const struct nla_policy hash_ip6_adt_policy[IPSET_ATTR_ADT_MAX + 1] = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, -}; - -static int -hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - union nf_inet_addr ip; - u32 timeout = h->timeout; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || - tb[IPSET_ATTR_IP_TO] || - tb[IPSET_ATTR_CIDR])) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &ip); - if (ret) - return ret; - - ip6_netmask(&ip, h->netmask); - if (ipv6_addr_any(&ip.in6)) - return -IPSET_ERR_HASH_ELEM; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - ret = adtfn(set, &ip, timeout, flags); - - return ip_set_eexist(ret, flags) ? 0 : ret; -} - -/* Create hash:ip type of sets */ - -static int -hash_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) -{ - u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; - u8 netmask, hbits; - struct ip_set_hash *h; - - if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) - return -IPSET_ERR_INVALID_FAMILY; - netmask = set->family == NFPROTO_IPV4 ? 32 : 128; - pr_debug("Create set %s with family %s\n", - set->name, set->family == NFPROTO_IPV4 ? "inet" : "inet6"); - - if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_HASHSIZE]) { - hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]); - if (hashsize < IPSET_MIMINAL_HASHSIZE) - hashsize = IPSET_MIMINAL_HASHSIZE; - } - - if (tb[IPSET_ATTR_MAXELEM]) - maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]); - - if (tb[IPSET_ATTR_NETMASK]) { - netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]); - - if ((set->family == NFPROTO_IPV4 && netmask > 32) || - (set->family == NFPROTO_IPV6 && netmask > 128) || - netmask == 0) - return -IPSET_ERR_INVALID_NETMASK; - } - - h = kzalloc(sizeof(*h), GFP_KERNEL); - if (!h) - return -ENOMEM; - - h->maxelem = maxelem; - h->netmask = netmask; - get_random_bytes(&h->initval, sizeof(h->initval)); - h->timeout = IPSET_NO_TIMEOUT; - - hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); - if (!h->table) { - kfree(h); - return -ENOMEM; - } - h->table->htable_bits = hbits; - - set->data = h; - - if (tb[IPSET_ATTR_TIMEOUT]) { - h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - - set->variant = set->family == NFPROTO_IPV4 - ? &hash_ip4_tvariant : &hash_ip6_tvariant; - - if (set->family == NFPROTO_IPV4) - hash_ip4_gc_init(set); - else - hash_ip6_gc_init(set); - } else { - set->variant = set->family == NFPROTO_IPV4 - ? &hash_ip4_variant : &hash_ip6_variant; - } - - pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n", - set->name, jhash_size(h->table->htable_bits), - h->table->htable_bits, h->maxelem, set->data, h->table); - - return 0; -} - -static struct ip_set_type hash_ip_type __read_mostly = { - .name = "hash:ip", - .protocol = IPSET_PROTOCOL, - .features = IPSET_TYPE_IP, - .dimension = IPSET_DIM_ONE, - .family = NFPROTO_UNSPEC, - .revision_min = 0, - .revision_max = 0, - .create = hash_ip_create, - .create_policy = { - [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, - [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 }, - [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, - [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_NETMASK] = { .type = NLA_U8 }, - }, - .adt_policy = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, - [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, - }, - .me = THIS_MODULE, -}; - -static int __init -hash_ip_init(void) -{ - return ip_set_type_register(&hash_ip_type); -} - -static void __exit -hash_ip_fini(void) -{ - ip_set_type_unregister(&hash_ip_type); -} - -module_init(hash_ip_init); -module_exit(hash_ip_fini); diff --git a/extensions/ipset-6/ip_set_hash_ipport.c b/extensions/ipset-6/ip_set_hash_ipport.c deleted file mode 100644 index 24d833f..0000000 --- a/extensions/ipset-6/ip_set_hash_ipport.c +++ /dev/null @@ -1,555 +0,0 @@ -/* Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module implementing an IP set type: the hash:ip,port type */ - -#include "jhash.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "pfxlen.h" -#include "ip_set.h" -#include "ip_set_timeout.h" -#include "ip_set_getport.h" -#include "ip_set_hash.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("hash:ip,port type of IP sets"); -MODULE_ALIAS("ip_set_hash:ip,port"); - -/* Type specific function prefix */ -#define TYPE hash_ipport - -static bool -hash_ipport_same_set(const struct ip_set *a, const struct ip_set *b); - -#define hash_ipport4_same_set hash_ipport_same_set -#define hash_ipport6_same_set hash_ipport_same_set - -/* The type variant functions: IPv4 */ - -/* Member elements without timeout */ -struct hash_ipport4_elem { - __be32 ip; - __be16 port; - u8 proto; - u8 padding; -}; - -/* Member elements with timeout support */ -struct hash_ipport4_telem { - __be32 ip; - __be16 port; - u8 proto; - u8 padding; - unsigned long timeout; -}; - -static inline bool -hash_ipport4_data_equal(const struct hash_ipport4_elem *ip1, - const struct hash_ipport4_elem *ip2, - u32 *multi) -{ - return ip1->ip == ip2->ip && - ip1->port == ip2->port && - ip1->proto == ip2->proto; -} - -static inline bool -hash_ipport4_data_isnull(const struct hash_ipport4_elem *elem) -{ - return elem->proto == 0; -} - -static inline void -hash_ipport4_data_copy(struct hash_ipport4_elem *dst, - const struct hash_ipport4_elem *src) -{ - dst->ip = src->ip; - dst->port = src->port; - dst->proto = src->proto; -} - -static inline void -hash_ipport4_data_zero_out(struct hash_ipport4_elem *elem) -{ - elem->proto = 0; -} - -static bool -hash_ipport4_data_list(struct sk_buff *skb, - const struct hash_ipport4_elem *data) -{ - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_ipport4_data_tlist(struct sk_buff *skb, - const struct hash_ipport4_elem *data) -{ - const struct hash_ipport4_telem *tdata = - (const struct hash_ipport4_telem *)data; - - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, tdata->port); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(tdata->timeout))); - - return 0; - -nla_put_failure: - return 1; -} - -#define PF 4 -#define HOST_MASK 32 -#include "ip_set_ahash.h" - -static inline void -hash_ipport4_data_next(struct ip_set_hash *h, - const struct hash_ipport4_elem *d) -{ - h->next.ip = ntohl(d->ip); - h->next.port = ntohs(d->port); -} - -static int -hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipport4_elem data = { }; - - if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, - &data.port, &data.proto)) - return -EINVAL; - - ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipport4_elem data = { }; - u32 ip, ip_to = 0, p = 0, port, port_to; - u32 timeout = h->timeout; - bool with_ports = false; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip); - if (ret) - return ret; - - if (tb[IPSET_ATTR_PORT]) - data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); - else - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_PROTO]) { - data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); - with_ports = ip_set_proto_with_ports(data.proto); - - if (data.proto == 0) - return -IPSET_ERR_INVALID_PROTO; - } else - return -IPSET_ERR_MISSING_PROTO; - - if (!(with_ports || data.proto == IPPROTO_ICMP)) - data.port = 0; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - if (adt == IPSET_TEST || - !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || - tb[IPSET_ATTR_PORT_TO])) { - ret = adtfn(set, &data, timeout, flags); - return ip_set_eexist(ret, flags) ? 0 : ret; - } - - ip = ntohl(data.ip); - if (tb[IPSET_ATTR_IP_TO]) { - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); - if (ret) - return ret; - if (ip > ip_to) - swap(ip, ip_to); - } else if (tb[IPSET_ATTR_CIDR]) { - u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - - if (cidr > 32) - return -IPSET_ERR_INVALID_CIDR; - ip_set_mask_from_to(ip, ip_to, cidr); - } else - ip_to = ip; - - port_to = port = ntohs(data.port); - if (with_ports && tb[IPSET_ATTR_PORT_TO]) { - port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); - if (port > port_to) - swap(port, port_to); - } - - if (retried) - ip = h->next.ip; - for (; !before(ip_to, ip); ip++) { - p = retried && ip == h->next.ip ? h->next.port : port; - for (; p <= port_to; p++) { - data.ip = htonl(ip); - data.port = htons(p); - ret = adtfn(set, &data, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - } - } - return ret; -} - -static bool -hash_ipport_same_set(const struct ip_set *a, const struct ip_set *b) -{ - const struct ip_set_hash *x = a->data; - const struct ip_set_hash *y = b->data; - - /* Resizing changes htable_bits, so we ignore it */ - return x->maxelem == y->maxelem && - x->timeout == y->timeout; -} - -/* The type variant functions: IPv6 */ - -struct hash_ipport6_elem { - union nf_inet_addr ip; - __be16 port; - u8 proto; - u8 padding; -}; - -struct hash_ipport6_telem { - union nf_inet_addr ip; - __be16 port; - u8 proto; - u8 padding; - unsigned long timeout; -}; - -static inline bool -hash_ipport6_data_equal(const struct hash_ipport6_elem *ip1, - const struct hash_ipport6_elem *ip2, - u32 *multi) -{ - return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && - ip1->port == ip2->port && - ip1->proto == ip2->proto; -} - -static inline bool -hash_ipport6_data_isnull(const struct hash_ipport6_elem *elem) -{ - return elem->proto == 0; -} - -static inline void -hash_ipport6_data_copy(struct hash_ipport6_elem *dst, - const struct hash_ipport6_elem *src) -{ - memcpy(dst, src, sizeof(*dst)); -} - -static inline void -hash_ipport6_data_zero_out(struct hash_ipport6_elem *elem) -{ - elem->proto = 0; -} - -static bool -hash_ipport6_data_list(struct sk_buff *skb, - const struct hash_ipport6_elem *data) -{ - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_ipport6_data_tlist(struct sk_buff *skb, - const struct hash_ipport6_elem *data) -{ - const struct hash_ipport6_telem *e = - (const struct hash_ipport6_telem *)data; - - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(e->timeout))); - return 0; - -nla_put_failure: - return 1; -} - -#undef PF -#undef HOST_MASK - -#define PF 6 -#define HOST_MASK 128 -#include "ip_set_ahash.h" - -static inline void -hash_ipport6_data_next(struct ip_set_hash *h, - const struct hash_ipport6_elem *d) -{ - h->next.port = ntohs(d->port); -} - -static int -hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipport6_elem data = { }; - - if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, - &data.port, &data.proto)) - return -EINVAL; - - ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipport6_elem data = { }; - u32 port, port_to; - u32 timeout = h->timeout; - bool with_ports = false; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || - tb[IPSET_ATTR_IP_TO] || - tb[IPSET_ATTR_CIDR])) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); - if (ret) - return ret; - - if (tb[IPSET_ATTR_PORT]) - data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); - else - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_PROTO]) { - data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); - with_ports = ip_set_proto_with_ports(data.proto); - - if (data.proto == 0) - return -IPSET_ERR_INVALID_PROTO; - } else - return -IPSET_ERR_MISSING_PROTO; - - if (!(with_ports || data.proto == IPPROTO_ICMPV6)) - data.port = 0; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { - ret = adtfn(set, &data, timeout, flags); - return ip_set_eexist(ret, flags) ? 0 : ret; - } - - port = ntohs(data.port); - port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); - if (port > port_to) - swap(port, port_to); - - if (retried) - port = h->next.port; - for (; port <= port_to; port++) { - data.port = htons(port); - ret = adtfn(set, &data, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - } - return ret; -} - -/* Create hash:ip type of sets */ - -static int -hash_ipport_create(struct ip_set *set, struct nlattr *tb[], u32 flags) -{ - struct ip_set_hash *h; - u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; - u8 hbits; - - if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) - return -IPSET_ERR_INVALID_FAMILY; - - if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_HASHSIZE]) { - hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]); - if (hashsize < IPSET_MIMINAL_HASHSIZE) - hashsize = IPSET_MIMINAL_HASHSIZE; - } - - if (tb[IPSET_ATTR_MAXELEM]) - maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]); - - h = kzalloc(sizeof(*h), GFP_KERNEL); - if (!h) - return -ENOMEM; - - h->maxelem = maxelem; - get_random_bytes(&h->initval, sizeof(h->initval)); - h->timeout = IPSET_NO_TIMEOUT; - - hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); - if (!h->table) { - kfree(h); - return -ENOMEM; - } - h->table->htable_bits = hbits; - - set->data = h; - - if (tb[IPSET_ATTR_TIMEOUT]) { - h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - - set->variant = set->family == NFPROTO_IPV4 - ? &hash_ipport4_tvariant : &hash_ipport6_tvariant; - - if (set->family == NFPROTO_IPV4) - hash_ipport4_gc_init(set); - else - hash_ipport6_gc_init(set); - } else { - set->variant = set->family == NFPROTO_IPV4 - ? &hash_ipport4_variant : &hash_ipport6_variant; - } - - pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n", - set->name, jhash_size(h->table->htable_bits), - h->table->htable_bits, h->maxelem, set->data, h->table); - - return 0; -} - -static struct ip_set_type hash_ipport_type __read_mostly = { - .name = "hash:ip,port", - .protocol = IPSET_PROTOCOL, - .features = IPSET_TYPE_IP | IPSET_TYPE_PORT, - .dimension = IPSET_DIM_TWO, - .family = NFPROTO_UNSPEC, - .revision_min = 0, - .revision_max = 1, /* SCTP and UDPLITE support added */ - .create = hash_ipport_create, - .create_policy = { - [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, - [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 }, - [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, - [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, - [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - }, - .adt_policy = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, - [IPSET_ATTR_PORT] = { .type = NLA_U16 }, - [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, - [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, - [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, - }, - .me = THIS_MODULE, -}; - -static int __init -hash_ipport_init(void) -{ - return ip_set_type_register(&hash_ipport_type); -} - -static void __exit -hash_ipport_fini(void) -{ - ip_set_type_unregister(&hash_ipport_type); -} - -module_init(hash_ipport_init); -module_exit(hash_ipport_fini); diff --git a/extensions/ipset-6/ip_set_hash_ipportip.c b/extensions/ipset-6/ip_set_hash_ipportip.c deleted file mode 100644 index d89a55a..0000000 --- a/extensions/ipset-6/ip_set_hash_ipportip.c +++ /dev/null @@ -1,573 +0,0 @@ -/* Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module implementing an IP set type: the hash:ip,port,ip type */ - -#include "jhash.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "pfxlen.h" -#include "ip_set.h" -#include "ip_set_timeout.h" -#include "ip_set_getport.h" -#include "ip_set_hash.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("hash:ip,port,ip type of IP sets"); -MODULE_ALIAS("ip_set_hash:ip,port,ip"); - -/* Type specific function prefix */ -#define TYPE hash_ipportip - -static bool -hash_ipportip_same_set(const struct ip_set *a, const struct ip_set *b); - -#define hash_ipportip4_same_set hash_ipportip_same_set -#define hash_ipportip6_same_set hash_ipportip_same_set - -/* The type variant functions: IPv4 */ - -/* Member elements without timeout */ -struct hash_ipportip4_elem { - __be32 ip; - __be32 ip2; - __be16 port; - u8 proto; - u8 padding; -}; - -/* Member elements with timeout support */ -struct hash_ipportip4_telem { - __be32 ip; - __be32 ip2; - __be16 port; - u8 proto; - u8 padding; - unsigned long timeout; -}; - -static inline bool -hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1, - const struct hash_ipportip4_elem *ip2, - u32 *multi) -{ - return ip1->ip == ip2->ip && - ip1->ip2 == ip2->ip2 && - ip1->port == ip2->port && - ip1->proto == ip2->proto; -} - -static inline bool -hash_ipportip4_data_isnull(const struct hash_ipportip4_elem *elem) -{ - return elem->proto == 0; -} - -static inline void -hash_ipportip4_data_copy(struct hash_ipportip4_elem *dst, - const struct hash_ipportip4_elem *src) -{ - memcpy(dst, src, sizeof(*dst)); -} - -static inline void -hash_ipportip4_data_zero_out(struct hash_ipportip4_elem *elem) -{ - elem->proto = 0; -} - -static bool -hash_ipportip4_data_list(struct sk_buff *skb, - const struct hash_ipportip4_elem *data) -{ - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip); - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP2, data->ip2); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_ipportip4_data_tlist(struct sk_buff *skb, - const struct hash_ipportip4_elem *data) -{ - const struct hash_ipportip4_telem *tdata = - (const struct hash_ipportip4_telem *)data; - - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip); - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP2, tdata->ip2); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, tdata->port); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(tdata->timeout))); - - return 0; - -nla_put_failure: - return 1; -} - -#define PF 4 -#define HOST_MASK 32 -#include "ip_set_ahash.h" - -static inline void -hash_ipportip4_data_next(struct ip_set_hash *h, - const struct hash_ipportip4_elem *d) -{ - h->next.ip = ntohl(d->ip); - h->next.port = ntohs(d->port); -} - -static int -hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipportip4_elem data = { }; - - if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, - &data.port, &data.proto)) - return -EINVAL; - - ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); - ip4addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2); - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipportip4_elem data = { }; - u32 ip, ip_to = 0, p = 0, port, port_to; - u32 timeout = h->timeout; - bool with_ports = false; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || - !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip); - if (ret) - return ret; - - ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP2], &data.ip2); - if (ret) - return ret; - - if (tb[IPSET_ATTR_PORT]) - data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); - else - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_PROTO]) { - data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); - with_ports = ip_set_proto_with_ports(data.proto); - - if (data.proto == 0) - return -IPSET_ERR_INVALID_PROTO; - } else - return -IPSET_ERR_MISSING_PROTO; - - if (!(with_ports || data.proto == IPPROTO_ICMP)) - data.port = 0; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - if (adt == IPSET_TEST || - !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || - tb[IPSET_ATTR_PORT_TO])) { - ret = adtfn(set, &data, timeout, flags); - return ip_set_eexist(ret, flags) ? 0 : ret; - } - - ip = ntohl(data.ip); - if (tb[IPSET_ATTR_IP_TO]) { - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); - if (ret) - return ret; - if (ip > ip_to) - swap(ip, ip_to); - } else if (tb[IPSET_ATTR_CIDR]) { - u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - - if (cidr > 32) - return -IPSET_ERR_INVALID_CIDR; - ip_set_mask_from_to(ip, ip_to, cidr); - } else - ip_to = ip; - - port_to = port = ntohs(data.port); - if (with_ports && tb[IPSET_ATTR_PORT_TO]) { - port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); - if (port > port_to) - swap(port, port_to); - } - - if (retried) - ip = h->next.ip; - for (; !before(ip_to, ip); ip++) { - p = retried && ip == h->next.ip ? h->next.port : port; - for (; p <= port_to; p++) { - data.ip = htonl(ip); - data.port = htons(p); - ret = adtfn(set, &data, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - } - } - return ret; -} - -static bool -hash_ipportip_same_set(const struct ip_set *a, const struct ip_set *b) -{ - const struct ip_set_hash *x = a->data; - const struct ip_set_hash *y = b->data; - - /* Resizing changes htable_bits, so we ignore it */ - return x->maxelem == y->maxelem && - x->timeout == y->timeout; -} - -/* The type variant functions: IPv6 */ - -struct hash_ipportip6_elem { - union nf_inet_addr ip; - union nf_inet_addr ip2; - __be16 port; - u8 proto; - u8 padding; -}; - -struct hash_ipportip6_telem { - union nf_inet_addr ip; - union nf_inet_addr ip2; - __be16 port; - u8 proto; - u8 padding; - unsigned long timeout; -}; - -static inline bool -hash_ipportip6_data_equal(const struct hash_ipportip6_elem *ip1, - const struct hash_ipportip6_elem *ip2, - u32 *multi) -{ - return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && - ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0 && - ip1->port == ip2->port && - ip1->proto == ip2->proto; -} - -static inline bool -hash_ipportip6_data_isnull(const struct hash_ipportip6_elem *elem) -{ - return elem->proto == 0; -} - -static inline void -hash_ipportip6_data_copy(struct hash_ipportip6_elem *dst, - const struct hash_ipportip6_elem *src) -{ - memcpy(dst, src, sizeof(*dst)); -} - -static inline void -hash_ipportip6_data_zero_out(struct hash_ipportip6_elem *elem) -{ - elem->proto = 0; -} - -static bool -hash_ipportip6_data_list(struct sk_buff *skb, - const struct hash_ipportip6_elem *data) -{ - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip); - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP2, &data->ip2); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_ipportip6_data_tlist(struct sk_buff *skb, - const struct hash_ipportip6_elem *data) -{ - const struct hash_ipportip6_telem *e = - (const struct hash_ipportip6_telem *)data; - - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip); - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP2, &data->ip2); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(e->timeout))); - return 0; - -nla_put_failure: - return 1; -} - -#undef PF -#undef HOST_MASK - -#define PF 6 -#define HOST_MASK 128 -#include "ip_set_ahash.h" - -static inline void -hash_ipportip6_data_next(struct ip_set_hash *h, - const struct hash_ipportip6_elem *d) -{ - h->next.port = ntohs(d->port); -} - -static int -hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipportip6_elem data = { }; - - if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, - &data.port, &data.proto)) - return -EINVAL; - - ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); - ip6addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2.in6); - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipportip6_elem data = { }; - u32 port, port_to; - u32 timeout = h->timeout; - bool with_ports = false; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || - !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || - tb[IPSET_ATTR_IP_TO] || - tb[IPSET_ATTR_CIDR])) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); - if (ret) - return ret; - - ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &data.ip2); - if (ret) - return ret; - - if (tb[IPSET_ATTR_PORT]) - data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); - else - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_PROTO]) { - data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); - with_ports = ip_set_proto_with_ports(data.proto); - - if (data.proto == 0) - return -IPSET_ERR_INVALID_PROTO; - } else - return -IPSET_ERR_MISSING_PROTO; - - if (!(with_ports || data.proto == IPPROTO_ICMPV6)) - data.port = 0; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { - ret = adtfn(set, &data, timeout, flags); - return ip_set_eexist(ret, flags) ? 0 : ret; - } - - port = ntohs(data.port); - port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); - if (port > port_to) - swap(port, port_to); - - if (retried) - port = h->next.port; - for (; port <= port_to; port++) { - data.port = htons(port); - ret = adtfn(set, &data, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - } - return ret; -} - -/* Create hash:ip type of sets */ - -static int -hash_ipportip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) -{ - struct ip_set_hash *h; - u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; - u8 hbits; - - if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) - return -IPSET_ERR_INVALID_FAMILY; - - if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_HASHSIZE]) { - hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]); - if (hashsize < IPSET_MIMINAL_HASHSIZE) - hashsize = IPSET_MIMINAL_HASHSIZE; - } - - if (tb[IPSET_ATTR_MAXELEM]) - maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]); - - h = kzalloc(sizeof(*h), GFP_KERNEL); - if (!h) - return -ENOMEM; - - h->maxelem = maxelem; - get_random_bytes(&h->initval, sizeof(h->initval)); - h->timeout = IPSET_NO_TIMEOUT; - - hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); - if (!h->table) { - kfree(h); - return -ENOMEM; - } - h->table->htable_bits = hbits; - - set->data = h; - - if (tb[IPSET_ATTR_TIMEOUT]) { - h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - - set->variant = set->family == NFPROTO_IPV4 - ? &hash_ipportip4_tvariant : &hash_ipportip6_tvariant; - - if (set->family == NFPROTO_IPV4) - hash_ipportip4_gc_init(set); - else - hash_ipportip6_gc_init(set); - } else { - set->variant = set->family == NFPROTO_IPV4 - ? &hash_ipportip4_variant : &hash_ipportip6_variant; - } - - pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n", - set->name, jhash_size(h->table->htable_bits), - h->table->htable_bits, h->maxelem, set->data, h->table); - - return 0; -} - -static struct ip_set_type hash_ipportip_type __read_mostly = { - .name = "hash:ip,port,ip", - .protocol = IPSET_PROTOCOL, - .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2, - .dimension = IPSET_DIM_THREE, - .family = NFPROTO_UNSPEC, - .revision_min = 0, - .revision_max = 1, /* SCTP and UDPLITE support added */ - .create = hash_ipportip_create, - .create_policy = { - [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, - [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 }, - [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, - [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - }, - .adt_policy = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP2] = { .type = NLA_NESTED }, - [IPSET_ATTR_PORT] = { .type = NLA_U16 }, - [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, - [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, - [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, - }, - .me = THIS_MODULE, -}; - -static int __init -hash_ipportip_init(void) -{ - return ip_set_type_register(&hash_ipportip_type); -} - -static void __exit -hash_ipportip_fini(void) -{ - ip_set_type_unregister(&hash_ipportip_type); -} - -module_init(hash_ipportip_init); -module_exit(hash_ipportip_fini); diff --git a/extensions/ipset-6/ip_set_hash_ipportnet.c b/extensions/ipset-6/ip_set_hash_ipportnet.c deleted file mode 100644 index 80daf8f..0000000 --- a/extensions/ipset-6/ip_set_hash_ipportnet.c +++ /dev/null @@ -1,665 +0,0 @@ -/* Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module implementing an IP set type: the hash:ip,port,net type */ - -#include "jhash.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "pfxlen.h" -#include "ip_set.h" -#include "ip_set_timeout.h" -#include "ip_set_getport.h" -#include "ip_set_hash.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("hash:ip,port,net type of IP sets"); -MODULE_ALIAS("ip_set_hash:ip,port,net"); - -/* Type specific function prefix */ -#define TYPE hash_ipportnet - -static bool -hash_ipportnet_same_set(const struct ip_set *a, const struct ip_set *b); - -#define hash_ipportnet4_same_set hash_ipportnet_same_set -#define hash_ipportnet6_same_set hash_ipportnet_same_set - -/* The type variant functions: IPv4 */ - -/* Member elements without timeout */ -struct hash_ipportnet4_elem { - __be32 ip; - __be32 ip2; - __be16 port; - u8 cidr; - u8 proto; -}; - -/* Member elements with timeout support */ -struct hash_ipportnet4_telem { - __be32 ip; - __be32 ip2; - __be16 port; - u8 cidr; - u8 proto; - unsigned long timeout; -}; - -static inline bool -hash_ipportnet4_data_equal(const struct hash_ipportnet4_elem *ip1, - const struct hash_ipportnet4_elem *ip2, - u32 *multi) -{ - return ip1->ip == ip2->ip && - ip1->ip2 == ip2->ip2 && - ip1->cidr == ip2->cidr && - ip1->port == ip2->port && - ip1->proto == ip2->proto; -} - -static inline bool -hash_ipportnet4_data_isnull(const struct hash_ipportnet4_elem *elem) -{ - return elem->proto == 0; -} - -static inline void -hash_ipportnet4_data_copy(struct hash_ipportnet4_elem *dst, - const struct hash_ipportnet4_elem *src) -{ - memcpy(dst, src, sizeof(*dst)); -} - -static inline void -hash_ipportnet4_data_netmask(struct hash_ipportnet4_elem *elem, u8 cidr) -{ - elem->ip2 &= ip_set_netmask(cidr); - elem->cidr = cidr; -} - -static inline void -hash_ipportnet4_data_zero_out(struct hash_ipportnet4_elem *elem) -{ - elem->proto = 0; -} - -static bool -hash_ipportnet4_data_list(struct sk_buff *skb, - const struct hash_ipportnet4_elem *data) -{ - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip); - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP2, data->ip2); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR2, data->cidr); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_ipportnet4_data_tlist(struct sk_buff *skb, - const struct hash_ipportnet4_elem *data) -{ - const struct hash_ipportnet4_telem *tdata = - (const struct hash_ipportnet4_telem *)data; - - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip); - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP2, tdata->ip2); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, tdata->port); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR2, data->cidr); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(tdata->timeout))); - - return 0; - -nla_put_failure: - return 1; -} - -#define IP_SET_HASH_WITH_PROTO -#define IP_SET_HASH_WITH_NETS - -#define PF 4 -#define HOST_MASK 32 -#include "ip_set_ahash.h" - -static inline void -hash_ipportnet4_data_next(struct ip_set_hash *h, - const struct hash_ipportnet4_elem *d) -{ - h->next.ip = ntohl(d->ip); - h->next.port = ntohs(d->port); - h->next.ip2 = ntohl(d->ip2); -} - -static int -hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipportnet4_elem data = { - .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK - }; - - if (data.cidr == 0) - return -EINVAL; - if (adt == IPSET_TEST) - data.cidr = HOST_MASK; - - if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, - &data.port, &data.proto)) - return -EINVAL; - - ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); - ip4addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2); - data.ip2 &= ip_set_netmask(data.cidr); - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipportnet4_elem data = { .cidr = HOST_MASK }; - u32 ip, ip_to = 0, p = 0, port, port_to; - u32 ip2_from = 0, ip2_to, ip2_last, ip2; - u32 timeout = h->timeout; - bool with_ports = false; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || - !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); - if (ret) - return ret; - - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2], &ip2_from); - if (ret) - return ret; - - if (tb[IPSET_ATTR_CIDR2]) { - data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR2]); - if (!data.cidr) - return -IPSET_ERR_INVALID_CIDR; - } - - if (tb[IPSET_ATTR_PORT]) - data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); - else - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_PROTO]) { - data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); - with_ports = ip_set_proto_with_ports(data.proto); - - if (data.proto == 0) - return -IPSET_ERR_INVALID_PROTO; - } else - return -IPSET_ERR_MISSING_PROTO; - - if (!(with_ports || data.proto == IPPROTO_ICMP)) - data.port = 0; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - with_ports = with_ports && tb[IPSET_ATTR_PORT_TO]; - if (adt == IPSET_TEST || - !(tb[IPSET_ATTR_CIDR] || tb[IPSET_ATTR_IP_TO] || with_ports || - tb[IPSET_ATTR_IP2_TO])) { - data.ip = htonl(ip); - data.ip2 = htonl(ip2_from & ip_set_hostmask(data.cidr)); - ret = adtfn(set, &data, timeout, flags); - return ip_set_eexist(ret, flags) ? 0 : ret; - } - - if (tb[IPSET_ATTR_IP_TO]) { - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); - if (ret) - return ret; - if (ip > ip_to) - swap(ip, ip_to); - } else if (tb[IPSET_ATTR_CIDR]) { - u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - - if (cidr > 32) - return -IPSET_ERR_INVALID_CIDR; - ip_set_mask_from_to(ip, ip_to, cidr); - } - - port_to = port = ntohs(data.port); - if (tb[IPSET_ATTR_PORT_TO]) { - port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); - if (port > port_to) - swap(port, port_to); - } - if (tb[IPSET_ATTR_IP2_TO]) { - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to); - if (ret) - return ret; - if (ip2_from > ip2_to) - swap(ip2_from, ip2_to); - if (ip2_from + UINT_MAX == ip2_to) - return -IPSET_ERR_HASH_RANGE; - } else { - ip_set_mask_from_to(ip2_from, ip2_to, data.cidr); - } - - if (retried) - ip = h->next.ip; - for (; !before(ip_to, ip); ip++) { - data.ip = htonl(ip); - p = retried && ip == h->next.ip ? h->next.port : port; - for (; p <= port_to; p++) { - data.port = htons(p); - ip2 = retried && ip == h->next.ip && p == h->next.port - ? h->next.ip2 : ip2_from; - while (!after(ip2, ip2_to)) { - data.ip2 = htonl(ip2); - ip2_last = ip_set_range_to_cidr(ip2, ip2_to, - &data.cidr); - ret = adtfn(set, &data, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - ip2 = ip2_last + 1; - } - } - } - return ret; -} - -static bool -hash_ipportnet_same_set(const struct ip_set *a, const struct ip_set *b) -{ - const struct ip_set_hash *x = a->data; - const struct ip_set_hash *y = b->data; - - /* Resizing changes htable_bits, so we ignore it */ - return x->maxelem == y->maxelem && - x->timeout == y->timeout; -} - -/* The type variant functions: IPv6 */ - -struct hash_ipportnet6_elem { - union nf_inet_addr ip; - union nf_inet_addr ip2; - __be16 port; - u8 cidr; - u8 proto; -}; - -struct hash_ipportnet6_telem { - union nf_inet_addr ip; - union nf_inet_addr ip2; - __be16 port; - u8 cidr; - u8 proto; - unsigned long timeout; -}; - -static inline bool -hash_ipportnet6_data_equal(const struct hash_ipportnet6_elem *ip1, - const struct hash_ipportnet6_elem *ip2, - u32 *multi) -{ - return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && - ipv6_addr_cmp(&ip1->ip2.in6, &ip2->ip2.in6) == 0 && - ip1->cidr == ip2->cidr && - ip1->port == ip2->port && - ip1->proto == ip2->proto; -} - -static inline bool -hash_ipportnet6_data_isnull(const struct hash_ipportnet6_elem *elem) -{ - return elem->proto == 0; -} - -static inline void -hash_ipportnet6_data_copy(struct hash_ipportnet6_elem *dst, - const struct hash_ipportnet6_elem *src) -{ - memcpy(dst, src, sizeof(*dst)); -} - -static inline void -hash_ipportnet6_data_zero_out(struct hash_ipportnet6_elem *elem) -{ - elem->proto = 0; -} - -static inline void -ip6_netmask(union nf_inet_addr *ip, u8 prefix) -{ - ip->ip6[0] &= ip_set_netmask6(prefix)[0]; - ip->ip6[1] &= ip_set_netmask6(prefix)[1]; - ip->ip6[2] &= ip_set_netmask6(prefix)[2]; - ip->ip6[3] &= ip_set_netmask6(prefix)[3]; -} - -static inline void -hash_ipportnet6_data_netmask(struct hash_ipportnet6_elem *elem, u8 cidr) -{ - ip6_netmask(&elem->ip2, cidr); - elem->cidr = cidr; -} - -static bool -hash_ipportnet6_data_list(struct sk_buff *skb, - const struct hash_ipportnet6_elem *data) -{ - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip); - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP2, &data->ip2); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR2, data->cidr); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_ipportnet6_data_tlist(struct sk_buff *skb, - const struct hash_ipportnet6_elem *data) -{ - const struct hash_ipportnet6_telem *e = - (const struct hash_ipportnet6_telem *)data; - - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip); - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP2, &data->ip2); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR2, data->cidr); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(e->timeout))); - return 0; - -nla_put_failure: - return 1; -} - -#undef PF -#undef HOST_MASK - -#define PF 6 -#define HOST_MASK 128 -#include "ip_set_ahash.h" - -static inline void -hash_ipportnet6_data_next(struct ip_set_hash *h, - const struct hash_ipportnet6_elem *d) -{ - h->next.port = ntohs(d->port); -} - -static int -hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipportnet6_elem data = { - .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK - }; - - if (data.cidr == 0) - return -EINVAL; - if (adt == IPSET_TEST) - data.cidr = HOST_MASK; - - if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, - &data.port, &data.proto)) - return -EINVAL; - - ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); - ip6addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2.in6); - ip6_netmask(&data.ip2, data.cidr); - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_ipportnet6_elem data = { .cidr = HOST_MASK }; - u32 port, port_to; - u32 timeout = h->timeout; - bool with_ports = false; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || - !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || - tb[IPSET_ATTR_IP_TO] || - tb[IPSET_ATTR_CIDR])) - return -IPSET_ERR_PROTOCOL; - if (unlikely(tb[IPSET_ATTR_IP_TO])) - return -IPSET_ERR_HASH_RANGE_UNSUPPORTED; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); - if (ret) - return ret; - - ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &data.ip2); - if (ret) - return ret; - - if (tb[IPSET_ATTR_CIDR2]) - data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR2]); - - if (!data.cidr) - return -IPSET_ERR_INVALID_CIDR; - - ip6_netmask(&data.ip2, data.cidr); - - if (tb[IPSET_ATTR_PORT]) - data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); - else - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_PROTO]) { - data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); - with_ports = ip_set_proto_with_ports(data.proto); - - if (data.proto == 0) - return -IPSET_ERR_INVALID_PROTO; - } else - return -IPSET_ERR_MISSING_PROTO; - - if (!(with_ports || data.proto == IPPROTO_ICMPV6)) - data.port = 0; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { - ret = adtfn(set, &data, timeout, flags); - return ip_set_eexist(ret, flags) ? 0 : ret; - } - - port = ntohs(data.port); - port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); - if (port > port_to) - swap(port, port_to); - - if (retried) - port = h->next.port; - for (; port <= port_to; port++) { - data.port = htons(port); - ret = adtfn(set, &data, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - } - return ret; -} - -/* Create hash:ip type of sets */ - -static int -hash_ipportnet_create(struct ip_set *set, struct nlattr *tb[], u32 flags) -{ - struct ip_set_hash *h; - u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; - u8 hbits; - - if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) - return -IPSET_ERR_INVALID_FAMILY; - - if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_HASHSIZE]) { - hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]); - if (hashsize < IPSET_MIMINAL_HASHSIZE) - hashsize = IPSET_MIMINAL_HASHSIZE; - } - - if (tb[IPSET_ATTR_MAXELEM]) - maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]); - - h = kzalloc(sizeof(*h) - + sizeof(struct ip_set_hash_nets) - * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL); - if (!h) - return -ENOMEM; - - h->maxelem = maxelem; - get_random_bytes(&h->initval, sizeof(h->initval)); - h->timeout = IPSET_NO_TIMEOUT; - - hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); - if (!h->table) { - kfree(h); - return -ENOMEM; - } - h->table->htable_bits = hbits; - - set->data = h; - - if (tb[IPSET_ATTR_TIMEOUT]) { - h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - - set->variant = set->family == NFPROTO_IPV4 - ? &hash_ipportnet4_tvariant - : &hash_ipportnet6_tvariant; - - if (set->family == NFPROTO_IPV4) - hash_ipportnet4_gc_init(set); - else - hash_ipportnet6_gc_init(set); - } else { - set->variant = set->family == NFPROTO_IPV4 - ? &hash_ipportnet4_variant : &hash_ipportnet6_variant; - } - - pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n", - set->name, jhash_size(h->table->htable_bits), - h->table->htable_bits, h->maxelem, set->data, h->table); - - return 0; -} - -static struct ip_set_type hash_ipportnet_type __read_mostly = { - .name = "hash:ip,port,net", - .protocol = IPSET_PROTOCOL, - .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2, - .dimension = IPSET_DIM_THREE, - .family = NFPROTO_UNSPEC, - .revision_min = 0, - /* 1 SCTP and UDPLITE support added */ - .revision_max = 2, /* Range as input support for IPv4 added */ - .create = hash_ipportnet_create, - .create_policy = { - [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, - [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 }, - [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, - [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - }, - .adt_policy = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP2] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP2_TO] = { .type = NLA_NESTED }, - [IPSET_ATTR_PORT] = { .type = NLA_U16 }, - [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, - [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, - [IPSET_ATTR_CIDR2] = { .type = NLA_U8 }, - [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, - }, - .me = THIS_MODULE, -}; - -static int __init -hash_ipportnet_init(void) -{ - return ip_set_type_register(&hash_ipportnet_type); -} - -static void __exit -hash_ipportnet_fini(void) -{ - ip_set_type_unregister(&hash_ipportnet_type); -} - -module_init(hash_ipportnet_init); -module_exit(hash_ipportnet_fini); diff --git a/extensions/ipset-6/ip_set_hash_net.c b/extensions/ipset-6/ip_set_hash_net.c deleted file mode 100644 index 479bee8..0000000 --- a/extensions/ipset-6/ip_set_hash_net.c +++ /dev/null @@ -1,508 +0,0 @@ -/* Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module implementing an IP set type: the hash:net type */ - -#include "jhash.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "pfxlen.h" -#include "ip_set.h" -#include "ip_set_timeout.h" -#include "ip_set_hash.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("hash:net type of IP sets"); -MODULE_ALIAS("ip_set_hash:net"); - -/* Type specific function prefix */ -#define TYPE hash_net - -static bool -hash_net_same_set(const struct ip_set *a, const struct ip_set *b); - -#define hash_net4_same_set hash_net_same_set -#define hash_net6_same_set hash_net_same_set - -/* The type variant functions: IPv4 */ - -/* Member elements without timeout */ -struct hash_net4_elem { - __be32 ip; - u16 padding0; - u8 padding1; - u8 cidr; -}; - -/* Member elements with timeout support */ -struct hash_net4_telem { - __be32 ip; - u16 padding0; - u8 padding1; - u8 cidr; - unsigned long timeout; -}; - -static inline bool -hash_net4_data_equal(const struct hash_net4_elem *ip1, - const struct hash_net4_elem *ip2, - u32 *multi) -{ - return ip1->ip == ip2->ip && ip1->cidr == ip2->cidr; -} - -static inline bool -hash_net4_data_isnull(const struct hash_net4_elem *elem) -{ - return elem->cidr == 0; -} - -static inline void -hash_net4_data_copy(struct hash_net4_elem *dst, - const struct hash_net4_elem *src) -{ - dst->ip = src->ip; - dst->cidr = src->cidr; -} - -static inline void -hash_net4_data_netmask(struct hash_net4_elem *elem, u8 cidr) -{ - elem->ip &= ip_set_netmask(cidr); - elem->cidr = cidr; -} - -/* Zero CIDR values cannot be stored */ -static inline void -hash_net4_data_zero_out(struct hash_net4_elem *elem) -{ - elem->cidr = 0; -} - -static bool -hash_net4_data_list(struct sk_buff *skb, const struct hash_net4_elem *data) -{ - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_net4_data_tlist(struct sk_buff *skb, const struct hash_net4_elem *data) -{ - const struct hash_net4_telem *tdata = - (const struct hash_net4_telem *)data; - - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, tdata->cidr); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(tdata->timeout))); - - return 0; - -nla_put_failure: - return 1; -} - -#define IP_SET_HASH_WITH_NETS - -#define PF 4 -#define HOST_MASK 32 -#include "ip_set_ahash.h" - -static inline void -hash_net4_data_next(struct ip_set_hash *h, - const struct hash_net4_elem *d) -{ - h->next.ip = ntohl(d->ip); -} - -static int -hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_net4_elem data = { - .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK - }; - - if (data.cidr == 0) - return -EINVAL; - if (adt == IPSET_TEST) - data.cidr = HOST_MASK; - - ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); - data.ip &= ip_set_netmask(data.cidr); - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_net4_elem data = { .cidr = HOST_MASK }; - u32 timeout = h->timeout; - u32 ip = 0, ip_to, last; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); - if (ret) - return ret; - - if (tb[IPSET_ATTR_CIDR]) { - data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - if (!data.cidr) - return -IPSET_ERR_INVALID_CIDR; - } - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) { - data.ip = htonl(ip & ip_set_hostmask(data.cidr)); - ret = adtfn(set, &data, timeout, flags); - return ip_set_eexist(ret, flags) ? 0 : ret; - } - - ip_to = ip; - if (tb[IPSET_ATTR_IP_TO]) { - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); - if (ret) - return ret; - if (ip_to < ip) - swap(ip, ip_to); - if (ip + UINT_MAX == ip_to) - return -IPSET_ERR_HASH_RANGE; - } - if (retried) - ip = h->next.ip; - while (!after(ip, ip_to)) { - data.ip = htonl(ip); - last = ip_set_range_to_cidr(ip, ip_to, &data.cidr); - ret = adtfn(set, &data, timeout, flags); - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - ip = last + 1; - } - return ret; -} - -static bool -hash_net_same_set(const struct ip_set *a, const struct ip_set *b) -{ - const struct ip_set_hash *x = a->data; - const struct ip_set_hash *y = b->data; - - /* Resizing changes htable_bits, so we ignore it */ - return x->maxelem == y->maxelem && - x->timeout == y->timeout; -} - -/* The type variant functions: IPv6 */ - -struct hash_net6_elem { - union nf_inet_addr ip; - u16 padding0; - u8 padding1; - u8 cidr; -}; - -struct hash_net6_telem { - union nf_inet_addr ip; - u16 padding0; - u8 padding1; - u8 cidr; - unsigned long timeout; -}; - -static inline bool -hash_net6_data_equal(const struct hash_net6_elem *ip1, - const struct hash_net6_elem *ip2, - u32 *multi) -{ - return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && - ip1->cidr == ip2->cidr; -} - -static inline bool -hash_net6_data_isnull(const struct hash_net6_elem *elem) -{ - return elem->cidr == 0; -} - -static inline void -hash_net6_data_copy(struct hash_net6_elem *dst, - const struct hash_net6_elem *src) -{ - dst->ip.in6 = src->ip.in6; - dst->cidr = src->cidr; -} - -static inline void -hash_net6_data_zero_out(struct hash_net6_elem *elem) -{ - elem->cidr = 0; -} - -static inline void -ip6_netmask(union nf_inet_addr *ip, u8 prefix) -{ - ip->ip6[0] &= ip_set_netmask6(prefix)[0]; - ip->ip6[1] &= ip_set_netmask6(prefix)[1]; - ip->ip6[2] &= ip_set_netmask6(prefix)[2]; - ip->ip6[3] &= ip_set_netmask6(prefix)[3]; -} - -static inline void -hash_net6_data_netmask(struct hash_net6_elem *elem, u8 cidr) -{ - ip6_netmask(&elem->ip, cidr); - elem->cidr = cidr; -} - -static bool -hash_net6_data_list(struct sk_buff *skb, const struct hash_net6_elem *data) -{ - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_net6_data_tlist(struct sk_buff *skb, const struct hash_net6_elem *data) -{ - const struct hash_net6_telem *e = - (const struct hash_net6_telem *)data; - - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, e->cidr); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(e->timeout))); - return 0; - -nla_put_failure: - return 1; -} - -#undef PF -#undef HOST_MASK - -#define PF 6 -#define HOST_MASK 128 -#include "ip_set_ahash.h" - -static inline void -hash_net6_data_next(struct ip_set_hash *h, - const struct hash_net6_elem *d) -{ -} - -static int -hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_net6_elem data = { - .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK - }; - - if (data.cidr == 0) - return -EINVAL; - if (adt == IPSET_TEST) - data.cidr = HOST_MASK; - - ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); - ip6_netmask(&data.ip, data.cidr); - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_net6_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_net6_elem data = { .cidr = HOST_MASK }; - u32 timeout = h->timeout; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - if (unlikely(tb[IPSET_ATTR_IP_TO])) - return -IPSET_ERR_HASH_RANGE_UNSUPPORTED; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); - if (ret) - return ret; - - if (tb[IPSET_ATTR_CIDR]) - data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - - if (!data.cidr) - return -IPSET_ERR_INVALID_CIDR; - - ip6_netmask(&data.ip, data.cidr); - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - ret = adtfn(set, &data, timeout, flags); - - return ip_set_eexist(ret, flags) ? 0 : ret; -} - -/* Create hash:ip type of sets */ - -static int -hash_net_create(struct ip_set *set, struct nlattr *tb[], u32 flags) -{ - u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; - struct ip_set_hash *h; - u8 hbits; - - if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) - return -IPSET_ERR_INVALID_FAMILY; - - if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_HASHSIZE]) { - hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]); - if (hashsize < IPSET_MIMINAL_HASHSIZE) - hashsize = IPSET_MIMINAL_HASHSIZE; - } - - if (tb[IPSET_ATTR_MAXELEM]) - maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]); - - h = kzalloc(sizeof(*h) - + sizeof(struct ip_set_hash_nets) - * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL); - if (!h) - return -ENOMEM; - - h->maxelem = maxelem; - get_random_bytes(&h->initval, sizeof(h->initval)); - h->timeout = IPSET_NO_TIMEOUT; - - hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); - if (!h->table) { - kfree(h); - return -ENOMEM; - } - h->table->htable_bits = hbits; - - set->data = h; - - if (tb[IPSET_ATTR_TIMEOUT]) { - h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - - set->variant = set->family == NFPROTO_IPV4 - ? &hash_net4_tvariant : &hash_net6_tvariant; - - if (set->family == NFPROTO_IPV4) - hash_net4_gc_init(set); - else - hash_net6_gc_init(set); - } else { - set->variant = set->family == NFPROTO_IPV4 - ? &hash_net4_variant : &hash_net6_variant; - } - - pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n", - set->name, jhash_size(h->table->htable_bits), - h->table->htable_bits, h->maxelem, set->data, h->table); - - return 0; -} - -static struct ip_set_type hash_net_type __read_mostly = { - .name = "hash:net", - .protocol = IPSET_PROTOCOL, - .features = IPSET_TYPE_IP, - .dimension = IPSET_DIM_ONE, - .family = NFPROTO_UNSPEC, - .revision_min = 0, - .revision_max = 1, /* Range as input support for IPv4 added */ - .create = hash_net_create, - .create_policy = { - [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, - [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 }, - [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, - [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - }, - .adt_policy = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, - [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - }, - .me = THIS_MODULE, -}; - -static int __init -hash_net_init(void) -{ - return ip_set_type_register(&hash_net_type); -} - -static void __exit -hash_net_fini(void) -{ - ip_set_type_unregister(&hash_net_type); -} - -module_init(hash_net_init); -module_exit(hash_net_fini); diff --git a/extensions/ipset-6/ip_set_hash_netiface.c b/extensions/ipset-6/ip_set_hash_netiface.c deleted file mode 100644 index d5ed56d..0000000 --- a/extensions/ipset-6/ip_set_hash_netiface.c +++ /dev/null @@ -1,786 +0,0 @@ -/* Copyright (C) 2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module implementing an IP set type: the hash:net,iface type */ - -#include "jhash.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "pfxlen.h" -#include "ip_set.h" -#include "ip_set_timeout.h" -#include "ip_set_hash.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("hash:net,iface type of IP sets"); -MODULE_ALIAS("ip_set_hash:net,iface"); - -/* Interface name rbtree */ - -struct iface_node { - struct rb_node node; - char iface[IFNAMSIZ]; -}; - -#define iface_data(n) (rb_entry(n, struct iface_node, node)->iface) - -static inline long -ifname_compare(const char *_a, const char *_b) -{ - const long *a = (const long *)_a; - const long *b = (const long *)_b; - - BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long)); - if (a[0] != b[0]) - return a[0] - b[0]; - if (IFNAMSIZ > sizeof(long)) { - if (a[1] != b[1]) - return a[1] - b[1]; - } - if (IFNAMSIZ > 2 * sizeof(long)) { - if (a[2] != b[2]) - return a[2] - b[2]; - } - if (IFNAMSIZ > 3 * sizeof(long)) { - if (a[3] != b[3]) - return a[3] - b[3]; - } - return 0; -} - -static void -rbtree_destroy(struct rb_root *root) -{ - struct rb_node *p, *n = root->rb_node; - struct iface_node *node; - - /* Non-recursive destroy, like in ext3 */ - while (n) { - if (n->rb_left) { - n = n->rb_left; - continue; - } - if (n->rb_right) { - n = n->rb_right; - continue; - } - p = rb_parent(n); - node = rb_entry(n, struct iface_node, node); - if (!p) - *root = RB_ROOT; - else if (p->rb_left == n) - p->rb_left = NULL; - else if (p->rb_right == n) - p->rb_right = NULL; - - kfree(node); - n = p; - } -} - -static int -iface_test(struct rb_root *root, const char **iface) -{ - struct rb_node *n = root->rb_node; - - while (n) { - const char *d = iface_data(n); - long res = ifname_compare(*iface, d); - - if (res < 0) - n = n->rb_left; - else if (res > 0) - n = n->rb_right; - else { - *iface = d; - return 1; - } - } - return 0; -} - -static int -iface_add(struct rb_root *root, const char **iface) -{ - struct rb_node **n = &(root->rb_node), *p = NULL; - struct iface_node *d; - - while (*n) { - char *ifname = iface_data(*n); - long res = ifname_compare(*iface, ifname); - - p = *n; - if (res < 0) - n = &((*n)->rb_left); - else if (res > 0) - n = &((*n)->rb_right); - else { - *iface = ifname; - return 0; - } - } - - d = kzalloc(sizeof(*d), GFP_ATOMIC); - if (!d) - return -ENOMEM; - strcpy(d->iface, *iface); - - rb_link_node(&d->node, p, n); - rb_insert_color(&d->node, root); - - *iface = d->iface; - return 0; -} - -/* Type specific function prefix */ -#define TYPE hash_netiface - -static bool -hash_netiface_same_set(const struct ip_set *a, const struct ip_set *b); - -#define hash_netiface4_same_set hash_netiface_same_set -#define hash_netiface6_same_set hash_netiface_same_set - -#define STREQ(a, b) (strcmp(a, b) == 0) - -/* The type variant functions: IPv4 */ - -struct hash_netiface4_elem_hashed { - __be32 ip; - u8 physdev; - u8 cidr; - u16 padding; -}; - -#define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed) - -/* Member elements without timeout */ -struct hash_netiface4_elem { - __be32 ip; - u8 physdev; - u8 cidr; - u16 padding; - const char *iface; -}; - -/* Member elements with timeout support */ -struct hash_netiface4_telem { - __be32 ip; - u8 physdev; - u8 cidr; - u16 padding; - const char *iface; - unsigned long timeout; -}; - -static inline bool -hash_netiface4_data_equal(const struct hash_netiface4_elem *ip1, - const struct hash_netiface4_elem *ip2, - u32 *multi) -{ - return ip1->ip == ip2->ip && - ip1->cidr == ip2->cidr && - (++*multi) && - ip1->physdev == ip2->physdev && - ip1->iface == ip2->iface; -} - -static inline bool -hash_netiface4_data_isnull(const struct hash_netiface4_elem *elem) -{ - return elem->cidr == 0; -} - -static inline void -hash_netiface4_data_copy(struct hash_netiface4_elem *dst, - const struct hash_netiface4_elem *src) { - dst->ip = src->ip; - dst->cidr = src->cidr; - dst->physdev = src->physdev; - dst->iface = src->iface; -} - -static inline void -hash_netiface4_data_netmask(struct hash_netiface4_elem *elem, u8 cidr) -{ - elem->ip &= ip_set_netmask(cidr); - elem->cidr = cidr; -} - -static inline void -hash_netiface4_data_zero_out(struct hash_netiface4_elem *elem) -{ - elem->cidr = 0; -} - -static bool -hash_netiface4_data_list(struct sk_buff *skb, - const struct hash_netiface4_elem *data) -{ - u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0; - - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr); - NLA_PUT_STRING(skb, IPSET_ATTR_IFACE, data->iface); - if (flags) - NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, flags); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_netiface4_data_tlist(struct sk_buff *skb, - const struct hash_netiface4_elem *data) -{ - const struct hash_netiface4_telem *tdata = - (const struct hash_netiface4_telem *)data; - u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0; - - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr); - NLA_PUT_STRING(skb, IPSET_ATTR_IFACE, data->iface); - if (flags) - NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, flags); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(tdata->timeout))); - - return 0; - -nla_put_failure: - return 1; -} - -#define IP_SET_HASH_WITH_NETS -#define IP_SET_HASH_WITH_RBTREE -#define IP_SET_HASH_WITH_MULTI - -#define PF 4 -#define HOST_MASK 32 -#include "ip_set_ahash.h" - -static inline void -hash_netiface4_data_next(struct ip_set_hash *h, - const struct hash_netiface4_elem *d) -{ - h->next.ip = ntohl(d->ip); -} - -static int -hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_netiface4_elem data = { - .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK - }; - int ret; - - if (data.cidr == 0) - return -EINVAL; - if (adt == IPSET_TEST) - data.cidr = HOST_MASK; - - ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); - data.ip &= ip_set_netmask(data.cidr); - -#define IFACE(dir) (par->dir ? par->dir->name : NULL) -#define PHYSDEV(dir) (nf_bridge->dir ? nf_bridge->dir->name : NULL) -#define SRCDIR (opt->flags & IPSET_DIM_TWO_SRC) - - if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { -#ifdef CONFIG_BRIDGE_NETFILTER - const struct nf_bridge_info *nf_bridge = skb->nf_bridge; - - if (!nf_bridge) - return -EINVAL; - data.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev); - data.physdev = 1; -#else - data.iface = NULL; -#endif - } else - data.iface = SRCDIR ? IFACE(in) : IFACE(out); - - if (!data.iface) - return -EINVAL; - ret = iface_test(&h->rbtree, &data.iface); - if (adt == IPSET_ADD) { - if (!ret) { - ret = iface_add(&h->rbtree, &data.iface); - if (ret) - return ret; - } - } else if (!ret) - return ret; - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_netiface4_elem data = { .cidr = HOST_MASK }; - u32 ip = 0, ip_to, last; - u32 timeout = h->timeout; - char iface[IFNAMSIZ] = {}; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !tb[IPSET_ATTR_IFACE] || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); - if (ret) - return ret; - - if (tb[IPSET_ATTR_CIDR]) { - data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - if (!data.cidr) - return -IPSET_ERR_INVALID_CIDR; - } - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - strcpy(iface, nla_data(tb[IPSET_ATTR_IFACE])); - data.iface = iface; - ret = iface_test(&h->rbtree, &data.iface); - if (adt == IPSET_ADD) { - if (!ret) { - ret = iface_add(&h->rbtree, &data.iface); - if (ret) - return ret; - } - } else if (!ret) - return ret; - - if (tb[IPSET_ATTR_CADT_FLAGS]) { - u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); - if (cadt_flags & IPSET_FLAG_PHYSDEV) - data.physdev = 1; - } - - if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) { - data.ip = htonl(ip & ip_set_hostmask(data.cidr)); - ret = adtfn(set, &data, timeout, flags); - return ip_set_eexist(ret, flags) ? 0 : ret; - } - - if (tb[IPSET_ATTR_IP_TO]) { - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); - if (ret) - return ret; - if (ip_to < ip) - swap(ip, ip_to); - if (ip + UINT_MAX == ip_to) - return -IPSET_ERR_HASH_RANGE; - } else { - ip_set_mask_from_to(ip, ip_to, data.cidr); - } - - if (retried) - ip = h->next.ip; - while (!after(ip, ip_to)) { - data.ip = htonl(ip); - last = ip_set_range_to_cidr(ip, ip_to, &data.cidr); - ret = adtfn(set, &data, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - ip = last + 1; - } - return ret; -} - -static bool -hash_netiface_same_set(const struct ip_set *a, const struct ip_set *b) -{ - const struct ip_set_hash *x = a->data; - const struct ip_set_hash *y = b->data; - - /* Resizing changes htable_bits, so we ignore it */ - return x->maxelem == y->maxelem && - x->timeout == y->timeout; -} - -/* The type variant functions: IPv6 */ - -struct hash_netiface6_elem_hashed { - union nf_inet_addr ip; - u8 physdev; - u8 cidr; - u16 padding; -}; - -#define HKEY_DATALEN sizeof(struct hash_netiface6_elem_hashed) - -struct hash_netiface6_elem { - union nf_inet_addr ip; - u8 physdev; - u8 cidr; - u16 padding; - const char *iface; -}; - -struct hash_netiface6_telem { - union nf_inet_addr ip; - u8 physdev; - u8 cidr; - u16 padding; - const char *iface; - unsigned long timeout; -}; - -static inline bool -hash_netiface6_data_equal(const struct hash_netiface6_elem *ip1, - const struct hash_netiface6_elem *ip2, - u32 *multi) -{ - return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && - ip1->cidr == ip2->cidr && - (++*multi) && - ip1->physdev == ip2->physdev && - ip1->iface == ip2->iface; -} - -static inline bool -hash_netiface6_data_isnull(const struct hash_netiface6_elem *elem) -{ - return elem->cidr == 0; -} - -static inline void -hash_netiface6_data_copy(struct hash_netiface6_elem *dst, - const struct hash_netiface6_elem *src) -{ - memcpy(dst, src, sizeof(*dst)); -} - -static inline void -hash_netiface6_data_zero_out(struct hash_netiface6_elem *elem) -{ -} - -static inline void -ip6_netmask(union nf_inet_addr *ip, u8 prefix) -{ - ip->ip6[0] &= ip_set_netmask6(prefix)[0]; - ip->ip6[1] &= ip_set_netmask6(prefix)[1]; - ip->ip6[2] &= ip_set_netmask6(prefix)[2]; - ip->ip6[3] &= ip_set_netmask6(prefix)[3]; -} - -static inline void -hash_netiface6_data_netmask(struct hash_netiface6_elem *elem, u8 cidr) -{ - ip6_netmask(&elem->ip, cidr); - elem->cidr = cidr; -} - -static bool -hash_netiface6_data_list(struct sk_buff *skb, - const struct hash_netiface6_elem *data) -{ - u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0; - - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr); - NLA_PUT_STRING(skb, IPSET_ATTR_IFACE, data->iface); - if (flags) - NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, flags); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_netiface6_data_tlist(struct sk_buff *skb, - const struct hash_netiface6_elem *data) -{ - const struct hash_netiface6_telem *e = - (const struct hash_netiface6_telem *)data; - u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0; - - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr); - NLA_PUT_STRING(skb, IPSET_ATTR_IFACE, data->iface); - if (flags) - NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, flags); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(e->timeout))); - return 0; - -nla_put_failure: - return 1; -} - -#undef PF -#undef HOST_MASK - -#define PF 6 -#define HOST_MASK 128 -#include "ip_set_ahash.h" - -static inline void -hash_netiface6_data_next(struct ip_set_hash *h, - const struct hash_netiface6_elem *d) -{ -} - -static int -hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_netiface6_elem data = { - .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK - }; - int ret; - - if (data.cidr == 0) - return -EINVAL; - if (adt == IPSET_TEST) - data.cidr = HOST_MASK; - - ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); - ip6_netmask(&data.ip, data.cidr); - - if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { -#ifdef CONFIG_BRIDGE_NETFILTER - const struct nf_bridge_info *nf_bridge = skb->nf_bridge; - - if (!nf_bridge) - return -EINVAL; - data.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev); - data.physdev = 1; -#else - data.iface = NULL; -#endif - } else - data.iface = SRCDIR ? IFACE(in) : IFACE(out); - - if (!data.iface) - return -EINVAL; - ret = iface_test(&h->rbtree, &data.iface); - if (adt == IPSET_ADD) { - if (!ret) { - ret = iface_add(&h->rbtree, &data.iface); - if (ret) - return ret; - } - } else if (!ret) - return ret; - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_netiface6_elem data = { .cidr = HOST_MASK }; - u32 timeout = h->timeout; - char iface[IFNAMSIZ] = {}; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !tb[IPSET_ATTR_IFACE] || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) - return -IPSET_ERR_PROTOCOL; - if (unlikely(tb[IPSET_ATTR_IP_TO])) - return -IPSET_ERR_HASH_RANGE_UNSUPPORTED; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); - if (ret) - return ret; - - if (tb[IPSET_ATTR_CIDR]) - data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - if (!data.cidr) - return -IPSET_ERR_INVALID_CIDR; - ip6_netmask(&data.ip, data.cidr); - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - strcpy(iface, nla_data(tb[IPSET_ATTR_IFACE])); - data.iface = iface; - ret = iface_test(&h->rbtree, &data.iface); - if (adt == IPSET_ADD) { - if (!ret) { - ret = iface_add(&h->rbtree, &data.iface); - if (ret) - return ret; - } - } else if (!ret) - return ret; - - if (tb[IPSET_ATTR_CADT_FLAGS]) { - u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); - if (cadt_flags & IPSET_FLAG_PHYSDEV) - data.physdev = 1; - } - - ret = adtfn(set, &data, timeout, flags); - - return ip_set_eexist(ret, flags) ? 0 : ret; -} - -/* Create hash:ip type of sets */ - -static int -hash_netiface_create(struct ip_set *set, struct nlattr *tb[], u32 flags) -{ - struct ip_set_hash *h; - u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; - u8 hbits; - - if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) - return -IPSET_ERR_INVALID_FAMILY; - - if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_HASHSIZE]) { - hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]); - if (hashsize < IPSET_MIMINAL_HASHSIZE) - hashsize = IPSET_MIMINAL_HASHSIZE; - } - - if (tb[IPSET_ATTR_MAXELEM]) - maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]); - - h = kzalloc(sizeof(*h) - + sizeof(struct ip_set_hash_nets) - * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL); - if (!h) - return -ENOMEM; - - h->maxelem = maxelem; - get_random_bytes(&h->initval, sizeof(h->initval)); - h->timeout = IPSET_NO_TIMEOUT; - h->ahash_max = AHASH_MAX_SIZE; - - hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); - if (!h->table) { - kfree(h); - return -ENOMEM; - } - h->table->htable_bits = hbits; - h->rbtree = RB_ROOT; - - set->data = h; - - if (tb[IPSET_ATTR_TIMEOUT]) { - h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - - set->variant = set->family == NFPROTO_IPV4 - ? &hash_netiface4_tvariant : &hash_netiface6_tvariant; - - if (set->family == NFPROTO_IPV4) - hash_netiface4_gc_init(set); - else - hash_netiface6_gc_init(set); - } else { - set->variant = set->family == NFPROTO_IPV4 - ? &hash_netiface4_variant : &hash_netiface6_variant; - } - - pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n", - set->name, jhash_size(h->table->htable_bits), - h->table->htable_bits, h->maxelem, set->data, h->table); - - return 0; -} - -static struct ip_set_type hash_netiface_type __read_mostly = { - .name = "hash:net,iface", - .protocol = IPSET_PROTOCOL, - .features = IPSET_TYPE_IP | IPSET_TYPE_IFACE, - .dimension = IPSET_DIM_TWO, - .family = NFPROTO_UNSPEC, - .revision_min = 0, - .create = hash_netiface_create, - .create_policy = { - [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, - [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 }, - [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, - [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, - [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - }, - .adt_policy = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, - [IPSET_ATTR_IFACE] = { .type = NLA_NUL_STRING, - .len = IPSET_MAXNAMELEN - 1 }, - [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, - [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, - }, - .me = THIS_MODULE, -}; - -static int __init -hash_netiface_init(void) -{ - return ip_set_type_register(&hash_netiface_type); -} - -static void __exit -hash_netiface_fini(void) -{ - ip_set_type_unregister(&hash_netiface_type); -} - -module_init(hash_netiface_init); -module_exit(hash_netiface_fini); diff --git a/extensions/ipset-6/ip_set_hash_netport.c b/extensions/ipset-6/ip_set_hash_netport.c deleted file mode 100644 index c6a2c27..0000000 --- a/extensions/ipset-6/ip_set_hash_netport.c +++ /dev/null @@ -1,615 +0,0 @@ -/* Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module implementing an IP set type: the hash:net,port type */ - -#include "jhash.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "pfxlen.h" -#include "ip_set.h" -#include "ip_set_timeout.h" -#include "ip_set_getport.h" -#include "ip_set_hash.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("hash:net,port type of IP sets"); -MODULE_ALIAS("ip_set_hash:net,port"); - -/* Type specific function prefix */ -#define TYPE hash_netport - -static bool -hash_netport_same_set(const struct ip_set *a, const struct ip_set *b); - -#define hash_netport4_same_set hash_netport_same_set -#define hash_netport6_same_set hash_netport_same_set - -/* The type variant functions: IPv4 */ - -/* Member elements without timeout */ -struct hash_netport4_elem { - __be32 ip; - __be16 port; - u8 proto; - u8 cidr; -}; - -/* Member elements with timeout support */ -struct hash_netport4_telem { - __be32 ip; - __be16 port; - u8 proto; - u8 cidr; - unsigned long timeout; -}; - -static inline bool -hash_netport4_data_equal(const struct hash_netport4_elem *ip1, - const struct hash_netport4_elem *ip2, - u32 *multi) -{ - return ip1->ip == ip2->ip && - ip1->port == ip2->port && - ip1->proto == ip2->proto && - ip1->cidr == ip2->cidr; -} - -static inline bool -hash_netport4_data_isnull(const struct hash_netport4_elem *elem) -{ - return elem->proto == 0; -} - -static inline void -hash_netport4_data_copy(struct hash_netport4_elem *dst, - const struct hash_netport4_elem *src) -{ - dst->ip = src->ip; - dst->port = src->port; - dst->proto = src->proto; - dst->cidr = src->cidr; -} - -static inline void -hash_netport4_data_netmask(struct hash_netport4_elem *elem, u8 cidr) -{ - elem->ip &= ip_set_netmask(cidr); - elem->cidr = cidr; -} - -static inline void -hash_netport4_data_zero_out(struct hash_netport4_elem *elem) -{ - elem->proto = 0; -} - -static bool -hash_netport4_data_list(struct sk_buff *skb, - const struct hash_netport4_elem *data) -{ - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_netport4_data_tlist(struct sk_buff *skb, - const struct hash_netport4_elem *data) -{ - const struct hash_netport4_telem *tdata = - (const struct hash_netport4_telem *)data; - - NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, tdata->port); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(tdata->timeout))); - - return 0; - -nla_put_failure: - return 1; -} - -#define IP_SET_HASH_WITH_PROTO -#define IP_SET_HASH_WITH_NETS - -#define PF 4 -#define HOST_MASK 32 -#include "ip_set_ahash.h" - -static inline void -hash_netport4_data_next(struct ip_set_hash *h, - const struct hash_netport4_elem *d) -{ - h->next.ip = ntohl(d->ip); - h->next.port = ntohs(d->port); -} - -static int -hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_netport4_elem data = { - .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK - }; - - if (data.cidr == 0) - return -EINVAL; - if (adt == IPSET_TEST) - data.cidr = HOST_MASK; - - if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, - &data.port, &data.proto)) - return -EINVAL; - - ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); - data.ip &= ip_set_netmask(data.cidr); - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_netport4_elem data = { .cidr = HOST_MASK }; - u32 port, port_to, p = 0, ip = 0, ip_to, last; - u32 timeout = h->timeout; - bool with_ports = false; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); - if (ret) - return ret; - - if (tb[IPSET_ATTR_CIDR]) { - data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - if (!data.cidr) - return -IPSET_ERR_INVALID_CIDR; - } - - if (tb[IPSET_ATTR_PORT]) - data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); - else - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_PROTO]) { - data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); - with_ports = ip_set_proto_with_ports(data.proto); - - if (data.proto == 0) - return -IPSET_ERR_INVALID_PROTO; - } else - return -IPSET_ERR_MISSING_PROTO; - - if (!(with_ports || data.proto == IPPROTO_ICMP)) - data.port = 0; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - with_ports = with_ports && tb[IPSET_ATTR_PORT_TO]; - if (adt == IPSET_TEST || !(with_ports || tb[IPSET_ATTR_IP_TO])) { - data.ip = htonl(ip & ip_set_hostmask(data.cidr)); - ret = adtfn(set, &data, timeout, flags); - return ip_set_eexist(ret, flags) ? 0 : ret; - } - - port = port_to = ntohs(data.port); - if (tb[IPSET_ATTR_PORT_TO]) { - port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); - if (port_to < port) - swap(port, port_to); - } - if (tb[IPSET_ATTR_IP_TO]) { - ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); - if (ret) - return ret; - if (ip_to < ip) - swap(ip, ip_to); - if (ip + UINT_MAX == ip_to) - return -IPSET_ERR_HASH_RANGE; - } else { - ip_set_mask_from_to(ip, ip_to, data.cidr); - } - - if (retried) - ip = h->next.ip; - while (!after(ip, ip_to)) { - data.ip = htonl(ip); - last = ip_set_range_to_cidr(ip, ip_to, &data.cidr); - p = retried && ip == h->next.ip ? h->next.port : port; - for (; p <= port_to; p++) { - data.port = htons(p); - ret = adtfn(set, &data, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - } - ip = last + 1; - } - return ret; -} - -static bool -hash_netport_same_set(const struct ip_set *a, const struct ip_set *b) -{ - const struct ip_set_hash *x = a->data; - const struct ip_set_hash *y = b->data; - - /* Resizing changes htable_bits, so we ignore it */ - return x->maxelem == y->maxelem && - x->timeout == y->timeout; -} - -/* The type variant functions: IPv6 */ - -struct hash_netport6_elem { - union nf_inet_addr ip; - __be16 port; - u8 proto; - u8 cidr; -}; - -struct hash_netport6_telem { - union nf_inet_addr ip; - __be16 port; - u8 proto; - u8 cidr; - unsigned long timeout; -}; - -static inline bool -hash_netport6_data_equal(const struct hash_netport6_elem *ip1, - const struct hash_netport6_elem *ip2, - u32 *multi) -{ - return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 && - ip1->port == ip2->port && - ip1->proto == ip2->proto && - ip1->cidr == ip2->cidr; -} - -static inline bool -hash_netport6_data_isnull(const struct hash_netport6_elem *elem) -{ - return elem->proto == 0; -} - -static inline void -hash_netport6_data_copy(struct hash_netport6_elem *dst, - const struct hash_netport6_elem *src) -{ - memcpy(dst, src, sizeof(*dst)); -} - -static inline void -hash_netport6_data_zero_out(struct hash_netport6_elem *elem) -{ - elem->proto = 0; -} - -static inline void -ip6_netmask(union nf_inet_addr *ip, u8 prefix) -{ - ip->ip6[0] &= ip_set_netmask6(prefix)[0]; - ip->ip6[1] &= ip_set_netmask6(prefix)[1]; - ip->ip6[2] &= ip_set_netmask6(prefix)[2]; - ip->ip6[3] &= ip_set_netmask6(prefix)[3]; -} - -static inline void -hash_netport6_data_netmask(struct hash_netport6_elem *elem, u8 cidr) -{ - ip6_netmask(&elem->ip, cidr); - elem->cidr = cidr; -} - -static bool -hash_netport6_data_list(struct sk_buff *skb, - const struct hash_netport6_elem *data) -{ - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - return 0; - -nla_put_failure: - return 1; -} - -static bool -hash_netport6_data_tlist(struct sk_buff *skb, - const struct hash_netport6_elem *data) -{ - const struct hash_netport6_telem *e = - (const struct hash_netport6_telem *)data; - - NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip); - NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port); - NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr); - NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(e->timeout))); - return 0; - -nla_put_failure: - return 1; -} - -#undef PF -#undef HOST_MASK - -#define PF 6 -#define HOST_MASK 128 -#include "ip_set_ahash.h" - -static inline void -hash_netport6_data_next(struct ip_set_hash *h, - const struct hash_netport6_elem *d) -{ - h->next.port = ntohs(d->port); -} - -static int -hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_netport6_elem data = { - .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK - }; - - if (data.cidr == 0) - return -EINVAL; - if (adt == IPSET_TEST) - data.cidr = HOST_MASK; - - if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, - &data.port, &data.proto)) - return -EINVAL; - - ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); - ip6_netmask(&data.ip, data.cidr); - - return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); -} - -static int -hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - const struct ip_set_hash *h = set->data; - ipset_adtfn adtfn = set->variant->adt[adt]; - struct hash_netport6_elem data = { .cidr = HOST_MASK }; - u32 port, port_to; - u32 timeout = h->timeout; - bool with_ports = false; - int ret; - - if (unlikely(!tb[IPSET_ATTR_IP] || - !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - if (unlikely(tb[IPSET_ATTR_IP_TO])) - return -IPSET_ERR_HASH_RANGE_UNSUPPORTED; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); - if (ret) - return ret; - - if (tb[IPSET_ATTR_CIDR]) - data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); - if (!data.cidr) - return -IPSET_ERR_INVALID_CIDR; - ip6_netmask(&data.ip, data.cidr); - - if (tb[IPSET_ATTR_PORT]) - data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); - else - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_PROTO]) { - data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); - with_ports = ip_set_proto_with_ports(data.proto); - - if (data.proto == 0) - return -IPSET_ERR_INVALID_PROTO; - } else - return -IPSET_ERR_MISSING_PROTO; - - if (!(with_ports || data.proto == IPPROTO_ICMPV6)) - data.port = 0; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout(h->timeout)) - return -IPSET_ERR_TIMEOUT; - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - - if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { - ret = adtfn(set, &data, timeout, flags); - return ip_set_eexist(ret, flags) ? 0 : ret; - } - - port = ntohs(data.port); - port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); - if (port > port_to) - swap(port, port_to); - - if (retried) - port = h->next.port; - for (; port <= port_to; port++) { - data.port = htons(port); - ret = adtfn(set, &data, timeout, flags); - - if (ret && !ip_set_eexist(ret, flags)) - return ret; - else - ret = 0; - } - return ret; -} - -/* Create hash:ip type of sets */ - -static int -hash_netport_create(struct ip_set *set, struct nlattr *tb[], u32 flags) -{ - struct ip_set_hash *h; - u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; - u8 hbits; - - if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) - return -IPSET_ERR_INVALID_FAMILY; - - if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_HASHSIZE]) { - hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]); - if (hashsize < IPSET_MIMINAL_HASHSIZE) - hashsize = IPSET_MIMINAL_HASHSIZE; - } - - if (tb[IPSET_ATTR_MAXELEM]) - maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]); - - h = kzalloc(sizeof(*h) - + sizeof(struct ip_set_hash_nets) - * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL); - if (!h) - return -ENOMEM; - - h->maxelem = maxelem; - get_random_bytes(&h->initval, sizeof(h->initval)); - h->timeout = IPSET_NO_TIMEOUT; - - hbits = htable_bits(hashsize); - h->table = ip_set_alloc( - sizeof(struct htable) - + jhash_size(hbits) * sizeof(struct hbucket)); - if (!h->table) { - kfree(h); - return -ENOMEM; - } - h->table->htable_bits = hbits; - - set->data = h; - - if (tb[IPSET_ATTR_TIMEOUT]) { - h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - - set->variant = set->family == NFPROTO_IPV4 - ? &hash_netport4_tvariant : &hash_netport6_tvariant; - - if (set->family == NFPROTO_IPV4) - hash_netport4_gc_init(set); - else - hash_netport6_gc_init(set); - } else { - set->variant = set->family == NFPROTO_IPV4 - ? &hash_netport4_variant : &hash_netport6_variant; - } - - pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n", - set->name, jhash_size(h->table->htable_bits), - h->table->htable_bits, h->maxelem, set->data, h->table); - - return 0; -} - -static struct ip_set_type hash_netport_type __read_mostly = { - .name = "hash:net,port", - .protocol = IPSET_PROTOCOL, - .features = IPSET_TYPE_IP | IPSET_TYPE_PORT, - .dimension = IPSET_DIM_TWO, - .family = NFPROTO_UNSPEC, - .revision_min = 0, - /* 1 SCTP and UDPLITE support added */ - .revision_max = 2, /* Range as input support for IPv4 added */ - .create = hash_netport_create, - .create_policy = { - [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, - [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 }, - [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, - [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, - [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - }, - .adt_policy = { - [IPSET_ATTR_IP] = { .type = NLA_NESTED }, - [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, - [IPSET_ATTR_PORT] = { .type = NLA_U16 }, - [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, - [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, - [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, - }, - .me = THIS_MODULE, -}; - -static int __init -hash_netport_init(void) -{ - return ip_set_type_register(&hash_netport_type); -} - -static void __exit -hash_netport_fini(void) -{ - ip_set_type_unregister(&hash_netport_type); -} - -module_init(hash_netport_init); -module_exit(hash_netport_fini); diff --git a/extensions/ipset-6/ip_set_list.h b/extensions/ipset-6/ip_set_list.h deleted file mode 100644 index 40a63f3..0000000 --- a/extensions/ipset-6/ip_set_list.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __IP_SET_LIST_H -#define __IP_SET_LIST_H - -/* List type specific error codes */ -enum { - /* Set name to be added/deleted/tested does not exist. */ - IPSET_ERR_NAME = IPSET_ERR_TYPE_SPECIFIC, - /* list:set type is not permitted to add */ - IPSET_ERR_LOOP, - /* Missing reference set */ - IPSET_ERR_BEFORE, - /* Reference set does not exist */ - IPSET_ERR_NAMEREF, - /* Set is full */ - IPSET_ERR_LIST_FULL, - /* Reference set is not added to the set */ - IPSET_ERR_REF_EXIST, -}; - -#ifdef __KERNEL__ - -#define IP_SET_LIST_DEFAULT_SIZE 8 -#define IP_SET_LIST_MIN_SIZE 4 - -#endif /* __KERNEL__ */ - -#endif /* __IP_SET_LIST_H */ diff --git a/extensions/ipset-6/ip_set_list_set.c b/extensions/ipset-6/ip_set_list_set.c deleted file mode 100644 index 070d086..0000000 --- a/extensions/ipset-6/ip_set_list_set.c +++ /dev/null @@ -1,611 +0,0 @@ -/* Copyright (C) 2008-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module implementing an IP set type: the list:set type */ - -#include -#include -#include -#include - -#include "ip_set.h" -#include "ip_set_timeout.h" -#include "ip_set_list.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("list:set type of IP sets"); -MODULE_ALIAS("ip_set_list:set"); - -/* Member elements without and with timeout */ -struct set_elem { - ip_set_id_t id; -}; - -struct set_telem { - ip_set_id_t id; - unsigned long timeout; -}; - -/* Type structure */ -struct list_set { - size_t dsize; /* element size */ - u32 size; /* size of set list array */ - u32 timeout; /* timeout value */ - struct timer_list gc; /* garbage collection */ - struct set_elem members[0]; /* the set members */ -}; - -static inline struct set_elem * -list_set_elem(const struct list_set *map, u32 id) -{ - return (struct set_elem *)((void *)map->members + id * map->dsize); -} - -static inline struct set_telem * -list_set_telem(const struct list_set *map, u32 id) -{ - return (struct set_telem *)((void *)map->members + id * map->dsize); -} - -static inline bool -list_set_timeout(const struct list_set *map, u32 id) -{ - const struct set_telem *elem = list_set_telem(map, id); - - return ip_set_timeout_test(elem->timeout); -} - -static inline bool -list_set_expired(const struct list_set *map, u32 id) -{ - const struct set_telem *elem = list_set_telem(map, id); - - return ip_set_timeout_expired(elem->timeout); -} - -/* Set list without and with timeout */ - -static int -list_set_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt) -{ - struct list_set *map = set->data; - struct set_elem *elem; - u32 i; - int ret; - - for (i = 0; i < map->size; i++) { - elem = list_set_elem(map, i); - if (elem->id == IPSET_INVALID_ID) - return 0; - if (with_timeout(map->timeout) && list_set_expired(map, i)) - continue; - switch (adt) { - case IPSET_TEST: - ret = ip_set_test(elem->id, skb, par, opt); - if (ret > 0) - return ret; - break; - case IPSET_ADD: - ret = ip_set_add(elem->id, skb, par, opt); - if (ret == 0) - return ret; - break; - case IPSET_DEL: - ret = ip_set_del(elem->id, skb, par, opt); - if (ret == 0) - return ret; - break; - default: - break; - } - } - return -EINVAL; -} - -static bool -id_eq(const struct list_set *map, u32 i, ip_set_id_t id) -{ - const struct set_elem *elem; - - if (i < map->size) { - elem = list_set_elem(map, i); - return elem->id == id; - } - - return 0; -} - -static bool -id_eq_timeout(const struct list_set *map, u32 i, ip_set_id_t id) -{ - const struct set_elem *elem; - - if (i < map->size) { - elem = list_set_elem(map, i); - return !!(elem->id == id && - !(with_timeout(map->timeout) && - list_set_expired(map, i))); - } - - return 0; -} - -static void -list_elem_add(struct list_set *map, u32 i, ip_set_id_t id) -{ - struct set_elem *e; - - for (; i < map->size; i++) { - e = list_set_elem(map, i); - swap(e->id, id); - if (e->id == IPSET_INVALID_ID) - break; - } -} - -static void -list_elem_tadd(struct list_set *map, u32 i, ip_set_id_t id, - unsigned long timeout) -{ - struct set_telem *e; - - for (; i < map->size; i++) { - e = list_set_telem(map, i); - swap(e->id, id); - swap(e->timeout, timeout); - if (e->id == IPSET_INVALID_ID) - break; - } -} - -static int -list_set_add(struct list_set *map, u32 i, ip_set_id_t id, - unsigned long timeout) -{ - const struct set_elem *e = list_set_elem(map, i); - - if (i == map->size - 1 && e->id != IPSET_INVALID_ID) - /* Last element replaced: e.g. add new,before,last */ - ip_set_put_byindex(e->id); - if (with_timeout(map->timeout)) - list_elem_tadd(map, i, id, ip_set_timeout_set(timeout)); - else - list_elem_add(map, i, id); - - return 0; -} - -static int -list_set_del(struct list_set *map, u32 i) -{ - struct set_elem *a = list_set_elem(map, i), *b; - - ip_set_put_byindex(a->id); - - for (; i < map->size - 1; i++) { - b = list_set_elem(map, i + 1); - a->id = b->id; - if (with_timeout(map->timeout)) - ((struct set_telem *)a)->timeout = - ((struct set_telem *)b)->timeout; - a = b; - if (a->id == IPSET_INVALID_ID) - break; - } - /* Last element */ - a->id = IPSET_INVALID_ID; - return 0; -} - -static void -cleanup_entries(struct list_set *map) -{ - struct set_telem *e; - u32 i; - - for (i = 0; i < map->size; i++) { - e = list_set_telem(map, i); - if (e->id != IPSET_INVALID_ID && list_set_expired(map, i)) - list_set_del(map, i); - } -} - -static int -list_set_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) -{ - struct list_set *map = set->data; - bool with_timeout = with_timeout(map->timeout); - bool flag_exist = flags & IPSET_FLAG_EXIST; - int before = 0; - u32 timeout = map->timeout; - ip_set_id_t id, refid = IPSET_INVALID_ID; - const struct set_elem *elem; - struct ip_set *s; - u32 i; - int ret = 0; - - if (unlikely(!tb[IPSET_ATTR_NAME] || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_LINENO]) - *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); - - id = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAME]), &s); - if (id == IPSET_INVALID_ID) - return -IPSET_ERR_NAME; - /* "Loop detection" */ - if (s->type->features & IPSET_TYPE_NAME) { - ret = -IPSET_ERR_LOOP; - goto finish; - } - - if (tb[IPSET_ATTR_CADT_FLAGS]) { - u32 f = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); - before = f & IPSET_FLAG_BEFORE; - } - - if (before && !tb[IPSET_ATTR_NAMEREF]) { - ret = -IPSET_ERR_BEFORE; - goto finish; - } - - if (tb[IPSET_ATTR_NAMEREF]) { - refid = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAMEREF]), - &s); - if (refid == IPSET_INVALID_ID) { - ret = -IPSET_ERR_NAMEREF; - goto finish; - } - if (!before) - before = -1; - } - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!with_timeout) { - ret = -IPSET_ERR_TIMEOUT; - goto finish; - } - timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); - } - if (with_timeout && adt != IPSET_TEST) - cleanup_entries(map); - - switch (adt) { - case IPSET_TEST: - for (i = 0; i < map->size && !ret; i++) { - elem = list_set_elem(map, i); - if (elem->id == IPSET_INVALID_ID || - (before != 0 && i + 1 >= map->size)) - break; - else if (with_timeout && list_set_expired(map, i)) - continue; - else if (before > 0 && elem->id == id) - ret = id_eq_timeout(map, i + 1, refid); - else if (before < 0 && elem->id == refid) - ret = id_eq_timeout(map, i + 1, id); - else if (before == 0 && elem->id == id) - ret = 1; - } - break; - case IPSET_ADD: - for (i = 0; i < map->size; i++) { - elem = list_set_elem(map, i); - if (elem->id != id) - continue; - if (!(with_timeout && flag_exist)) { - ret = -IPSET_ERR_EXIST; - goto finish; - } else { - struct set_telem *e = list_set_telem(map, i); - - if ((before > 1 && - !id_eq(map, i + 1, refid)) || - (before < 0 && - (i == 0 || !id_eq(map, i - 1, refid)))) { - ret = -IPSET_ERR_EXIST; - goto finish; - } - e->timeout = ip_set_timeout_set(timeout); - ip_set_put_byindex(id); - ret = 0; - goto finish; - } - } - ret = -IPSET_ERR_LIST_FULL; - for (i = 0; i < map->size && ret == -IPSET_ERR_LIST_FULL; i++) { - elem = list_set_elem(map, i); - if (elem->id == IPSET_INVALID_ID) - ret = before != 0 ? -IPSET_ERR_REF_EXIST - : list_set_add(map, i, id, timeout); - else if (elem->id != refid) - continue; - else if (before > 0) - ret = list_set_add(map, i, id, timeout); - else if (i + 1 < map->size) - ret = list_set_add(map, i + 1, id, timeout); - } - break; - case IPSET_DEL: - ret = -IPSET_ERR_EXIST; - for (i = 0; i < map->size && ret == -IPSET_ERR_EXIST; i++) { - elem = list_set_elem(map, i); - if (elem->id == IPSET_INVALID_ID) { - ret = before != 0 ? -IPSET_ERR_REF_EXIST - : -IPSET_ERR_EXIST; - break; - } else if (elem->id == id && - (before == 0 || - (before > 0 && id_eq(map, i + 1, refid)))) - ret = list_set_del(map, i); - else if (elem->id == refid && - before < 0 && id_eq(map, i + 1, id)) - ret = list_set_del(map, i + 1); - } - break; - default: - break; - } - -finish: - if (refid != IPSET_INVALID_ID) - ip_set_put_byindex(refid); - if (adt != IPSET_ADD || ret) - ip_set_put_byindex(id); - - return ip_set_eexist(ret, flags) ? 0 : ret; -} - -static void -list_set_flush(struct ip_set *set) -{ - struct list_set *map = set->data; - struct set_elem *elem; - u32 i; - - for (i = 0; i < map->size; i++) { - elem = list_set_elem(map, i); - if (elem->id != IPSET_INVALID_ID) { - ip_set_put_byindex(elem->id); - elem->id = IPSET_INVALID_ID; - } - } -} - -static void -list_set_destroy(struct ip_set *set) -{ - struct list_set *map = set->data; - - if (with_timeout(map->timeout)) - del_timer_sync(&map->gc); - list_set_flush(set); - kfree(map); - - set->data = NULL; -} - -static int -list_set_head(struct ip_set *set, struct sk_buff *skb) -{ - const struct list_set *map = set->data; - struct nlattr *nested; - - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) - goto nla_put_failure; - NLA_PUT_NET32(skb, IPSET_ATTR_SIZE, htonl(map->size)); - if (with_timeout(map->timeout)) - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout)); - NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); - NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, - htonl(sizeof(*map) + map->size * map->dsize)); - ipset_nest_end(skb, nested); - - return 0; -nla_put_failure: - return -EMSGSIZE; -} - -static int -list_set_list(const struct ip_set *set, - struct sk_buff *skb, struct netlink_callback *cb) -{ - const struct list_set *map = set->data; - struct nlattr *atd, *nested; - u32 i, first = cb->args[2]; - const struct set_elem *e; - - atd = ipset_nest_start(skb, IPSET_ATTR_ADT); - if (!atd) - return -EMSGSIZE; - for (; cb->args[2] < map->size; cb->args[2]++) { - i = cb->args[2]; - e = list_set_elem(map, i); - if (e->id == IPSET_INVALID_ID) - goto finish; - if (with_timeout(map->timeout) && list_set_expired(map, i)) - continue; - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) { - if (i == first) { - nla_nest_cancel(skb, atd); - return -EMSGSIZE; - } else - goto nla_put_failure; - } - NLA_PUT_STRING(skb, IPSET_ATTR_NAME, - ip_set_name_byindex(e->id)); - if (with_timeout(map->timeout)) { - const struct set_telem *te = - (const struct set_telem *) e; - NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, - htonl(ip_set_timeout_get(te->timeout))); - } - ipset_nest_end(skb, nested); - } -finish: - ipset_nest_end(skb, atd); - /* Set listing finished */ - cb->args[2] = 0; - return 0; - -nla_put_failure: - nla_nest_cancel(skb, nested); - ipset_nest_end(skb, atd); - if (unlikely(i == first)) { - cb->args[2] = 0; - return -EMSGSIZE; - } - return 0; -} - -static bool -list_set_same_set(const struct ip_set *a, const struct ip_set *b) -{ - const struct list_set *x = a->data; - const struct list_set *y = b->data; - - return x->size == y->size && - x->timeout == y->timeout; -} - -static const struct ip_set_type_variant list_set = { - .kadt = list_set_kadt, - .uadt = list_set_uadt, - .destroy = list_set_destroy, - .flush = list_set_flush, - .head = list_set_head, - .list = list_set_list, - .same_set = list_set_same_set, -}; - -static void -list_set_gc(unsigned long ul_set) -{ - struct ip_set *set = (struct ip_set *) ul_set; - struct list_set *map = set->data; - - write_lock_bh(&set->lock); - cleanup_entries(map); - write_unlock_bh(&set->lock); - - map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; - add_timer(&map->gc); -} - -static void -list_set_gc_init(struct ip_set *set) -{ - struct list_set *map = set->data; - - init_timer(&map->gc); - map->gc.data = (unsigned long) set; - map->gc.function = list_set_gc; - map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; - add_timer(&map->gc); -} - -/* Create list:set type of sets */ - -static bool -init_list_set(struct ip_set *set, u32 size, size_t dsize, - unsigned long timeout) -{ - struct list_set *map; - struct set_elem *e; - u32 i; - - map = kzalloc(sizeof(*map) + size * dsize, GFP_KERNEL); - if (!map) - return false; - - map->size = size; - map->dsize = dsize; - map->timeout = timeout; - set->data = map; - - for (i = 0; i < size; i++) { - e = list_set_elem(map, i); - e->id = IPSET_INVALID_ID; - } - - return true; -} - -static int -list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags) -{ - u32 size = IP_SET_LIST_DEFAULT_SIZE; - - if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_SIZE) || - !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) - return -IPSET_ERR_PROTOCOL; - - if (tb[IPSET_ATTR_SIZE]) - size = ip_set_get_h32(tb[IPSET_ATTR_SIZE]); - if (size < IP_SET_LIST_MIN_SIZE) - size = IP_SET_LIST_MIN_SIZE; - - if (tb[IPSET_ATTR_TIMEOUT]) { - if (!init_list_set(set, size, sizeof(struct set_telem), - ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]))) - return -ENOMEM; - - list_set_gc_init(set); - } else { - if (!init_list_set(set, size, sizeof(struct set_elem), - IPSET_NO_TIMEOUT)) - return -ENOMEM; - } - set->variant = &list_set; - return 0; -} - -static struct ip_set_type list_set_type __read_mostly = { - .name = "list:set", - .protocol = IPSET_PROTOCOL, - .features = IPSET_TYPE_NAME | IPSET_DUMP_LAST, - .dimension = IPSET_DIM_ONE, - .family = NFPROTO_UNSPEC, - .revision_min = 0, - .revision_max = 0, - .create = list_set_create, - .create_policy = { - [IPSET_ATTR_SIZE] = { .type = NLA_U32 }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - }, - .adt_policy = { - [IPSET_ATTR_NAME] = { .type = NLA_STRING, - .len = IPSET_MAXNAMELEN }, - [IPSET_ATTR_NAMEREF] = { .type = NLA_STRING, - .len = IPSET_MAXNAMELEN }, - [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, - [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, - [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, - }, - .me = THIS_MODULE, -}; - -static int __init -list_set_init(void) -{ - return ip_set_type_register(&list_set_type); -} - -static void __exit -list_set_fini(void) -{ - ip_set_type_unregister(&list_set_type); -} - -module_init(list_set_init); -module_exit(list_set_fini); diff --git a/extensions/ipset-6/ip_set_timeout.h b/extensions/ipset-6/ip_set_timeout.h deleted file mode 100644 index 4792320..0000000 --- a/extensions/ipset-6/ip_set_timeout.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef _IP_SET_TIMEOUT_H -#define _IP_SET_TIMEOUT_H - -/* Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifdef __KERNEL__ - -/* How often should the gc be run by default */ -#define IPSET_GC_TIME (3 * 60) - -/* Timeout period depending on the timeout value of the given set */ -#define IPSET_GC_PERIOD(timeout) \ - ((timeout/3) ? min_t(u32, (timeout)/3, IPSET_GC_TIME) : 1) - -/* Set is defined without timeout support: timeout value may be 0 */ -#define IPSET_NO_TIMEOUT UINT_MAX - -#define with_timeout(timeout) ((timeout) != IPSET_NO_TIMEOUT) - -#define opt_timeout(opt, map) \ - (with_timeout((opt)->timeout) ? (opt)->timeout : (map)->timeout) - -static inline unsigned int -ip_set_timeout_uget(struct nlattr *tb) -{ - unsigned int timeout = ip_set_get_h32(tb); - - /* Userspace supplied TIMEOUT parameter: adjust crazy size */ - return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout; -} - -#ifdef IP_SET_BITMAP_TIMEOUT - -/* Bitmap specific timeout constants and macros for the entries */ - -/* Bitmap entry is unset */ -#define IPSET_ELEM_UNSET 0 -/* Bitmap entry is set with no timeout value */ -#define IPSET_ELEM_PERMANENT (UINT_MAX/2) - -static inline bool -ip_set_timeout_test(unsigned long timeout) -{ - return timeout != IPSET_ELEM_UNSET && - (timeout == IPSET_ELEM_PERMANENT || - time_is_after_jiffies(timeout)); -} - -static inline bool -ip_set_timeout_expired(unsigned long timeout) -{ - return timeout != IPSET_ELEM_UNSET && - timeout != IPSET_ELEM_PERMANENT && - time_is_before_jiffies(timeout); -} - -static inline unsigned long -ip_set_timeout_set(u32 timeout) -{ - unsigned long t; - - if (!timeout) - return IPSET_ELEM_PERMANENT; - - t = msecs_to_jiffies(timeout * 1000) + jiffies; - if (t == IPSET_ELEM_UNSET || t == IPSET_ELEM_PERMANENT) - /* Bingo! */ - t++; - - return t; -} - -static inline u32 -ip_set_timeout_get(unsigned long timeout) -{ - return timeout == IPSET_ELEM_PERMANENT ? 0 : - jiffies_to_msecs(timeout - jiffies)/1000; -} - -#else - -/* Hash specific timeout constants and macros for the entries */ - -/* Hash entry is set with no timeout value */ -#define IPSET_ELEM_PERMANENT 0 - -static inline bool -ip_set_timeout_test(unsigned long timeout) -{ - return timeout == IPSET_ELEM_PERMANENT || - time_is_after_jiffies(timeout); -} - -static inline bool -ip_set_timeout_expired(unsigned long timeout) -{ - return timeout != IPSET_ELEM_PERMANENT && - time_is_before_jiffies(timeout); -} - -static inline unsigned long -ip_set_timeout_set(u32 timeout) -{ - unsigned long t; - - if (!timeout) - return IPSET_ELEM_PERMANENT; - - t = msecs_to_jiffies(timeout * 1000) + jiffies; - if (t == IPSET_ELEM_PERMANENT) - /* Bingo! :-) */ - t++; - - return t; -} - -static inline u32 -ip_set_timeout_get(unsigned long timeout) -{ - return timeout == IPSET_ELEM_PERMANENT ? 0 : - jiffies_to_msecs(timeout - jiffies)/1000; -} -#endif /* ! IP_SET_BITMAP_TIMEOUT */ - -#endif /* __KERNEL__ */ - -#endif /* _IP_SET_TIMEOUT_H */ diff --git a/extensions/ipset-6/jhash.h b/extensions/ipset-6/jhash.h deleted file mode 100644 index 72ca901..0000000 --- a/extensions/ipset-6/jhash.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef _LINUX_JHASH_H -#define _LINUX_JHASH_H - -/* jhash.h: Jenkins hash support. - * - * Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net) - * - * http://burtleburtle.net/bob/hash/ - * - * These are the credits from Bob's sources: - * - * lookup3.c, by Bob Jenkins, May 2006, Public Domain. - * - * These are functions for producing 32-bit hashes for hash table lookup. - * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() - * are externally useful functions. Routines to test the hash are included - * if SELF_TEST is defined. You can use this free for any purpose. It's in - * the public domain. It has no warranty. - * - * Copyright (C) 2009-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * I've modified Bob's hash to be useful in the Linux kernel, and - * any bugs present are my fault. - * Jozsef - */ -#include -#include - -/* Best hash sizes are of power of two */ -#define jhash_size(n) ((u32)1<<(n)) -/* Mask the hash value, i.e (value & jhash_mask(n)) instead of (value % n) */ -#define jhash_mask(n) (jhash_size(n)-1) - -/* __jhash_mix -- mix 3 32-bit values reversibly. */ -#define __jhash_mix(a, b, c) \ -{ \ - a -= c; a ^= rol32(c, 4); c += b; \ - b -= a; b ^= rol32(a, 6); a += c; \ - c -= b; c ^= rol32(b, 8); b += a; \ - a -= c; a ^= rol32(c, 16); c += b; \ - b -= a; b ^= rol32(a, 19); a += c; \ - c -= b; c ^= rol32(b, 4); b += a; \ -} - -/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */ -#define __jhash_final(a, b, c) \ -{ \ - c ^= b; c -= rol32(b, 14); \ - a ^= c; a -= rol32(c, 11); \ - b ^= a; b -= rol32(a, 25); \ - c ^= b; c -= rol32(b, 16); \ - a ^= c; a -= rol32(c, 4); \ - b ^= a; b -= rol32(a, 14); \ - c ^= b; c -= rol32(b, 24); \ -} - -/* An arbitrary initial parameter */ -#define JHASH_INITVAL 0xdeadbeef - -/* jhash - hash an arbitrary key - * @k: sequence of bytes as key - * @length: the length of the key - * @initval: the previous hash, or an arbitray value - * - * The generic version, hashes an arbitrary sequence of bytes. - * No alignment or length assumptions are made about the input key. - * - * Returns the hash value of the key. The result depends on endianness. - */ -static inline u32 jhash(const void *key, u32 length, u32 initval) -{ - u32 a, b, c; - const u8 *k = key; - - /* Set up the internal state */ - a = b = c = JHASH_INITVAL + length + initval; - - /* All but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) { - a += __get_unaligned_cpu32(k); - b += __get_unaligned_cpu32(k + 4); - c += __get_unaligned_cpu32(k + 8); - __jhash_mix(a, b, c); - length -= 12; - k += 12; - } - /* Last block: affect all 32 bits of (c) */ - /* All the case statements fall through */ - switch (length) { - case 12: c += (u32)k[11]<<24; - case 11: c += (u32)k[10]<<16; - case 10: c += (u32)k[9]<<8; - case 9: c += k[8]; - case 8: b += (u32)k[7]<<24; - case 7: b += (u32)k[6]<<16; - case 6: b += (u32)k[5]<<8; - case 5: b += k[4]; - case 4: a += (u32)k[3]<<24; - case 3: a += (u32)k[2]<<16; - case 2: a += (u32)k[1]<<8; - case 1: a += k[0]; - __jhash_final(a, b, c); - case 0: /* Nothing left to add */ - break; - } - - return c; -} - -/* jhash2 - hash an array of u32's - * @k: the key which must be an array of u32's - * @length: the number of u32's in the key - * @initval: the previous hash, or an arbitray value - * - * Returns the hash value of the key. - */ -static inline u32 jhash2(const u32 *k, u32 length, u32 initval) -{ - u32 a, b, c; - - /* Set up the internal state */ - a = b = c = JHASH_INITVAL + (length<<2) + initval; - - /* Handle most of the key */ - while (length > 3) { - a += k[0]; - b += k[1]; - c += k[2]; - __jhash_mix(a, b, c); - length -= 3; - k += 3; - } - - /* Handle the last 3 u32's: all the case statements fall through */ - switch (length) { - case 3: c += k[2]; - case 2: b += k[1]; - case 1: a += k[0]; - __jhash_final(a, b, c); - case 0: /* Nothing left to add */ - break; - } - - return c; -} - -/* jhash_3words - hash exactly 3, 2 or 1 word(s) */ -static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval) -{ - a += JHASH_INITVAL; - b += JHASH_INITVAL; - c += initval; - - __jhash_final(a, b, c); - - return c; -} - -static inline u32 jhash_2words(u32 a, u32 b, u32 initval) -{ - return jhash_3words(a, b, 0, initval); -} - -static inline u32 jhash_1word(u32 a, u32 initval) -{ - return jhash_3words(a, 0, 0, initval); -} - -#endif /* _LINUX_JHASH_H */ diff --git a/extensions/ipset-6/libipset/data.c b/extensions/ipset-6/libipset/data.c deleted file mode 100644 index 0210b7b..0000000 --- a/extensions/ipset-6/libipset/data.c +++ /dev/null @@ -1,588 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* assert */ -#include /* ntoh* */ -#include /* ETH_ALEN */ -#include /* IFNAMSIZ */ -#include /* malloc, free */ -#include /* memset */ - -#include /* IPSET_MAXNAMELEN */ -#include /* D() */ -#include /* struct ipset_type */ -#include /* inXcpy */ -#include /* prototypes */ - -/* Internal data structure to hold - * a) input data entered by the user or - * b) data received from kernel - * - * We always store the data in host order, *except* IP addresses. - */ - -struct ipset_data { - /* Option bits: which fields are set */ - uint64_t bits; - /* Option bits: which options are ignored */ - uint64_t ignored; - /* Setname */ - char setname[IPSET_MAXNAMELEN]; - /* Set type */ - const struct ipset_type *type; - /* Common CADT options */ - uint8_t cidr; - uint8_t family; - uint32_t flags; /* command level flags */ - uint32_t cadt_flags; /* data level flags */ - uint32_t timeout; - union nf_inet_addr ip; - union nf_inet_addr ip_to; - uint16_t port; - uint16_t port_to; - union { - /* RENAME/SWAP */ - char setname2[IPSET_MAXNAMELEN]; - /* CREATE/LIST/SAVE */ - struct { - uint8_t probes; - uint8_t resize; - uint8_t netmask; - uint32_t hashsize; - uint32_t maxelem; - uint32_t gc; - uint32_t size; - /* Filled out by kernel */ - uint32_t references; - uint32_t elements; - uint32_t memsize; - char typename[IPSET_MAXNAMELEN]; - uint8_t revision_min; - uint8_t revision; - } create; - /* ADT/LIST/SAVE */ - struct { - union nf_inet_addr ip2; - union nf_inet_addr ip2_to; - uint8_t cidr2; - uint8_t proto; - char ether[ETH_ALEN]; - char name[IPSET_MAXNAMELEN]; - char nameref[IPSET_MAXNAMELEN]; - char iface[IFNAMSIZ]; - } adt; - }; -}; - -static void -copy_addr(uint8_t family, union nf_inet_addr *ip, const void *value) -{ - if (family == NFPROTO_IPV4) - in4cpy(&ip->in, value); - else - in6cpy(&ip->in6, value); -} - -/** - * ipset_strlcpy - copy the string from src to dst - * @dst: the target string buffer - * @src: the source string buffer - * @len: the length of bytes to copy, including the terminating null byte. - * - * Copy the string from src to destination, but at most len bytes are - * copied. The target is unconditionally terminated by the null byte. - */ -void -ipset_strlcpy(char *dst, const char *src, size_t len) -{ - assert(dst); - assert(src); - - strncpy(dst, src, len); - dst[len - 1] = '\0'; -} - -/** - * ipset_data_flags_test - test option bits in the data blob - * @data: data blob - * @flags: the option flags to test - * - * Returns true if the options are already set in the data blob. - */ -bool -ipset_data_flags_test(const struct ipset_data *data, uint64_t flags) -{ - assert(data); - return !!(data->bits & flags); -} - -/** - * ipset_data_flags_set - set option bits in the data blob - * @data: data blob - * @flags: the option flags to set - * - * The function sets the flags in the data blob so that - * the corresponding fields are regarded as if filled with proper data. - */ -void -ipset_data_flags_set(struct ipset_data *data, uint64_t flags) -{ - assert(data); - data->bits |= flags; -} - -/** - * ipset_data_flags_unset - unset option bits in the data blob - * @data: data blob - * @flags: the option flags to unset - * - * The function unsets the flags in the data blob. - * This is the quick way to clear specific fields. - */ -void -ipset_data_flags_unset(struct ipset_data *data, uint64_t flags) -{ - assert(data); - data->bits &= ~flags; -} - -#define flag_type_attr(data, opt, flag) \ -do { \ - data->flags |= flag; \ - opt = IPSET_OPT_FLAGS; \ -} while (0) - -#define cadt_flag_type_attr(data, opt, flag) \ -do { \ - data->cadt_flags |= flag; \ - opt = IPSET_OPT_CADT_FLAGS; \ -} while (0) - -/** - * ipset_data_ignored - test and set ignored bits in the data blob - * @data: data blob - * @flags: the option flag to be ignored - * - * Returns true if the option was not already ignored. - */ -bool -ipset_data_ignored(struct ipset_data *data, enum ipset_opt opt) -{ - bool ignored; - assert(data); - - ignored = data->ignored & IPSET_FLAG(opt); - data->ignored |= IPSET_FLAG(opt); - - return ignored; -} - -/** - * ipset_data_set - put data into the data blob - * @data: data blob - * @opt: the option kind of the data - * @value: the value of the data - * - * Put a given kind of data into the data blob and mark the - * option kind as already set in the blob. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value) -{ - assert(data); - assert(opt != IPSET_OPT_NONE); - assert(value); - - switch (opt) { - /* Common ones */ - case IPSET_SETNAME: - ipset_strlcpy(data->setname, value, IPSET_MAXNAMELEN); - break; - case IPSET_OPT_TYPE: - data->type = value; - break; - case IPSET_OPT_FAMILY: - data->family = *(const uint8_t *) value; - D("family set to %u", data->family); - break; - /* CADT options */ - case IPSET_OPT_IP: - if (!(data->family == NFPROTO_IPV4 || data->family == NFPROTO_IPV6)) - return -1; - copy_addr(data->family, &data->ip, value); - break; - case IPSET_OPT_IP_TO: - if (!(data->family == NFPROTO_IPV4 || data->family == NFPROTO_IPV6)) - return -1; - copy_addr(data->family, &data->ip_to, value); - break; - case IPSET_OPT_CIDR: - data->cidr = *(const uint8_t *) value; - break; - case IPSET_OPT_PORT: - data->port = *(const uint16_t *) value; - break; - case IPSET_OPT_PORT_TO: - data->port_to = *(const uint16_t *) value; - break; - case IPSET_OPT_TIMEOUT: - data->timeout = *(const uint32_t *) value; - break; - /* Create-specific options */ - case IPSET_OPT_GC: - data->create.gc = *(const uint32_t *) value; - break; - case IPSET_OPT_HASHSIZE: - data->create.hashsize = *(const uint32_t *) value; - break; - case IPSET_OPT_MAXELEM: - data->create.maxelem = *(const uint32_t *) value; - break; - case IPSET_OPT_NETMASK: - data->create.netmask = *(const uint8_t *) value; - break; - case IPSET_OPT_PROBES: - data->create.probes = *(const uint8_t *) value; - break; - case IPSET_OPT_RESIZE: - data->create.resize = *(const uint8_t *) value; - break; - case IPSET_OPT_SIZE: - data->create.size = *(const uint32_t *) value; - break; - /* Create-specific options, filled out by the kernel */ - case IPSET_OPT_ELEMENTS: - data->create.elements = *(const uint32_t *) value; - break; - case IPSET_OPT_REFERENCES: - data->create.references = *(const uint32_t *) value; - break; - case IPSET_OPT_MEMSIZE: - data->create.memsize = *(const uint32_t *) value; - break; - /* Create-specific options, type */ - case IPSET_OPT_TYPENAME: - ipset_strlcpy(data->create.typename, value, - IPSET_MAXNAMELEN); - break; - case IPSET_OPT_REVISION: - data->create.revision = *(const uint8_t *) value; - break; - case IPSET_OPT_REVISION_MIN: - data->create.revision_min = *(const uint8_t *) value; - break; - /* ADT-specific options */ - case IPSET_OPT_ETHER: - memcpy(data->adt.ether, value, ETH_ALEN); - break; - case IPSET_OPT_NAME: - ipset_strlcpy(data->adt.name, value, IPSET_MAXNAMELEN); - break; - case IPSET_OPT_NAMEREF: - ipset_strlcpy(data->adt.nameref, value, IPSET_MAXNAMELEN); - break; - case IPSET_OPT_IP2: - if (!(data->family == NFPROTO_IPV4 || data->family == NFPROTO_IPV6)) - return -1; - copy_addr(data->family, &data->adt.ip2, value); - break; - case IPSET_OPT_IP2_TO: - if (!(data->family == NFPROTO_IPV4 || data->family == NFPROTO_IPV6)) - return -1; - copy_addr(data->family, &data->adt.ip2_to, value); - break; - case IPSET_OPT_CIDR2: - data->adt.cidr2 = *(const uint8_t *) value; - break; - case IPSET_OPT_PROTO: - data->adt.proto = *(const uint8_t *) value; - break; - case IPSET_OPT_IFACE: - ipset_strlcpy(data->adt.iface, value, IFNAMSIZ); - break; - /* Swap/rename */ - case IPSET_OPT_SETNAME2: - ipset_strlcpy(data->setname2, value, IPSET_MAXNAMELEN); - break; - /* flags */ - case IPSET_OPT_EXIST: - flag_type_attr(data, opt, IPSET_FLAG_EXIST); - break; - case IPSET_OPT_BEFORE: - cadt_flag_type_attr(data, opt, IPSET_FLAG_BEFORE); - break; - case IPSET_OPT_PHYSDEV: - cadt_flag_type_attr(data, opt, IPSET_FLAG_PHYSDEV); - break; - case IPSET_OPT_FLAGS: - data->flags = *(const uint32_t *)value; - break; - case IPSET_OPT_CADT_FLAGS: - data->cadt_flags = *(const uint32_t *)value; - break; - default: - return -1; - }; - - ipset_data_flags_set(data, IPSET_FLAG(opt)); - return 0; -} - -/** - * ipset_data_get - get data from the data blob - * @data: data blob - * @opt: option kind of the requested data - * - * Returns the pointer to the requested kind of data from the data blob - * if it is set. If the option kind is not set or is an unkown type, - * NULL is returned. - */ -const void * -ipset_data_get(const struct ipset_data *data, enum ipset_opt opt) -{ - assert(data); - assert(opt != IPSET_OPT_NONE); - - if (!(opt == IPSET_OPT_TYPENAME || ipset_data_test(data, opt))) - return NULL; - - switch (opt) { - /* Common ones */ - case IPSET_SETNAME: - return data->setname; - case IPSET_OPT_TYPE: - return data->type; - case IPSET_OPT_TYPENAME: - if (ipset_data_test(data, IPSET_OPT_TYPE)) - return data->type->name; - else if (ipset_data_test(data, IPSET_OPT_TYPENAME)) - return data->create.typename; - return NULL; - case IPSET_OPT_FAMILY: - return &data->family; - /* CADT options */ - case IPSET_OPT_IP: - return &data->ip; - case IPSET_OPT_IP_TO: - return &data->ip_to; - case IPSET_OPT_CIDR: - return &data->cidr; - case IPSET_OPT_PORT: - return &data->port; - case IPSET_OPT_PORT_TO: - return &data->port_to; - case IPSET_OPT_TIMEOUT: - return &data->timeout; - /* Create-specific options */ - case IPSET_OPT_GC: - return &data->create.gc; - case IPSET_OPT_HASHSIZE: - return &data->create.hashsize; - case IPSET_OPT_MAXELEM: - return &data->create.maxelem; - case IPSET_OPT_NETMASK: - return &data->create.netmask; - case IPSET_OPT_PROBES: - return &data->create.probes; - case IPSET_OPT_RESIZE: - return &data->create.resize; - case IPSET_OPT_SIZE: - return &data->create.size; - /* Create-specific options, filled out by the kernel */ - case IPSET_OPT_ELEMENTS: - return &data->create.elements; - case IPSET_OPT_REFERENCES: - return &data->create.references; - case IPSET_OPT_MEMSIZE: - return &data->create.memsize; - /* Create-specific options, TYPE */ - case IPSET_OPT_REVISION: - return &data->create.revision; - case IPSET_OPT_REVISION_MIN: - return &data->create.revision_min; - /* ADT-specific options */ - case IPSET_OPT_ETHER: - return data->adt.ether; - case IPSET_OPT_NAME: - return data->adt.name; - case IPSET_OPT_NAMEREF: - return data->adt.nameref; - case IPSET_OPT_IP2: - return &data->adt.ip2; - case IPSET_OPT_IP2_TO: - return &data->adt.ip2_to; - case IPSET_OPT_CIDR2: - return &data->adt.cidr2; - case IPSET_OPT_PROTO: - return &data->adt.proto; - case IPSET_OPT_IFACE: - return &data->adt.iface; - /* Swap/rename */ - case IPSET_OPT_SETNAME2: - return data->setname2; - /* flags */ - case IPSET_OPT_FLAGS: - case IPSET_OPT_EXIST: - return &data->flags; - case IPSET_OPT_CADT_FLAGS: - case IPSET_OPT_BEFORE: - case IPSET_OPT_PHYSDEV: - return &data->cadt_flags; - default: - return NULL; - } -} - -/** - * ipset_data_sizeof - calculates the size of the data type - * @opt: option kind of the data - * @family: INET family - * - * Returns the size required to store the given data type. - */ -size_t -ipset_data_sizeof(enum ipset_opt opt, uint8_t family) -{ - assert(opt != IPSET_OPT_NONE); - - switch (opt) { - case IPSET_OPT_IP: - case IPSET_OPT_IP_TO: - case IPSET_OPT_IP2: - case IPSET_OPT_IP2_TO: - return family == NFPROTO_IPV4 ? sizeof(uint32_t) - : sizeof(struct in6_addr); - case IPSET_OPT_PORT: - case IPSET_OPT_PORT_TO: - return sizeof(uint16_t); - case IPSET_SETNAME: - case IPSET_OPT_NAME: - case IPSET_OPT_NAMEREF: - return IPSET_MAXNAMELEN; - case IPSET_OPT_TIMEOUT: - case IPSET_OPT_GC: - case IPSET_OPT_HASHSIZE: - case IPSET_OPT_MAXELEM: - case IPSET_OPT_SIZE: - case IPSET_OPT_ELEMENTS: - case IPSET_OPT_REFERENCES: - case IPSET_OPT_MEMSIZE: - return sizeof(uint32_t); - case IPSET_OPT_CIDR: - case IPSET_OPT_CIDR2: - case IPSET_OPT_NETMASK: - case IPSET_OPT_PROBES: - case IPSET_OPT_RESIZE: - case IPSET_OPT_PROTO: - return sizeof(uint8_t); - case IPSET_OPT_ETHER: - return ETH_ALEN; - /* Flags doesn't counted once :-( */ - case IPSET_OPT_BEFORE: - case IPSET_OPT_PHYSDEV: - return sizeof(uint32_t); - default: - return 0; - }; -} - -/** - * ipset_setname - return the name of the set from the data blob - * @data: data blob - * - * Return the name of the set from the data blob or NULL if the - * name not set yet. - */ -const char * -ipset_data_setname(const struct ipset_data *data) -{ - assert(data); - return ipset_data_test(data, IPSET_SETNAME) ? data->setname : NULL; -} - -/** - * ipset_family - return the INET family of the set from the data blob - * @data: data blob - * - * Return the INET family supported by the set from the data blob. - * If the family is not set yet, NFPROTO_UNSPEC is returned. - */ -uint8_t -ipset_data_family(const struct ipset_data *data) -{ - assert(data); - return ipset_data_test(data, IPSET_OPT_FAMILY) - ? data->family : NFPROTO_UNSPEC; -} - -/** - * ipset_data_cidr - return the value of IPSET_OPT_CIDR - * @data: data blob - * - * Return the value of IPSET_OPT_CIDR stored in the data blob. - * If it is not set, then the returned value corresponds to - * the default one according to the family type or zero. - */ -uint8_t -ipset_data_cidr(const struct ipset_data *data) -{ - assert(data); - return ipset_data_test(data, IPSET_OPT_CIDR) ? data->cidr : - data->family == NFPROTO_IPV4 ? 32 : - data->family == NFPROTO_IPV6 ? 128 : 0; -} - -/** - * ipset_flags - return which fields are set in the data blob - * @data: data blob - * - * Returns the value of the bit field which elements are set. - */ -uint64_t -ipset_data_flags(const struct ipset_data *data) -{ - assert(data); - return data->bits; -} - -/** - * ipset_data_reset - reset the data blob to unset - * @data: data blob - * - * Resets the data blob to the unset state for every field. - */ -void -ipset_data_reset(struct ipset_data *data) -{ - assert(data); - memset(data, 0, sizeof(*data)); -} - -/** - * ipset_data_init - create a new data blob - * - * Return the new data blob initialized to empty. In case of - * an error, NULL is retured. - */ -struct ipset_data * -ipset_data_init(void) -{ - return calloc(1, sizeof(struct ipset_data)); -} - -/** - * ipset_data_fini - release a data blob created by ipset_data_init - * - * Release the data blob created by ipset_data_init previously. - */ -void -ipset_data_fini(struct ipset_data *data) -{ - assert(data); - free(data); -} diff --git a/extensions/ipset-6/libipset/debug.c b/extensions/ipset-6/libipset/debug.c deleted file mode 100644 index 486d910..0000000 --- a/extensions/ipset-6/libipset/debug.c +++ /dev/null @@ -1,288 +0,0 @@ -/* Copyright 2011 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include /* inet_ntop */ -#include /* libmnl backend */ - -struct ipset_attrname { - const char *name; -}; - -static const struct ipset_attrname cmdattr2name[] = { - [IPSET_ATTR_PROTOCOL] = { .name = "PROTOCOL" }, - [IPSET_ATTR_SETNAME] = { .name = "SETNAME" }, - [IPSET_ATTR_TYPENAME] = { .name = "TYPENAME" }, - [IPSET_ATTR_REVISION] = { .name = "REVISION" }, - [IPSET_ATTR_FAMILY] = { .name = "FAMILY" }, - [IPSET_ATTR_FLAGS] = { .name = "FLAGS" }, - [IPSET_ATTR_DATA] = { .name = "DATA" }, - [IPSET_ATTR_ADT] = { .name = "ADT" }, - [IPSET_ATTR_LINENO] = { .name = "LINENO" }, - [IPSET_ATTR_PROTOCOL_MIN] = { .name = "PROTO_MIN" }, -}; - -static const struct ipset_attrname createattr2name[] = { - [IPSET_ATTR_IP] = { .name = "IP" }, - [IPSET_ATTR_IP_TO] = { .name = "IP_TO" }, - [IPSET_ATTR_CIDR] = { .name = "CIDR" }, - [IPSET_ATTR_PORT] = { .name = "PORT" }, - [IPSET_ATTR_PORT_TO] = { .name = "PORT_TO" }, - [IPSET_ATTR_TIMEOUT] = { .name = "TIMEOUT" }, - [IPSET_ATTR_PROTO] = { .name = "PROTO" }, - [IPSET_ATTR_CADT_FLAGS] = { .name = "CADT_FLAGS" }, - [IPSET_ATTR_CADT_LINENO] = { .name = "CADT_LINENO" }, - [IPSET_ATTR_GC] = { .name = "GC" }, - [IPSET_ATTR_HASHSIZE] = { .name = "HASHSIZE" }, - [IPSET_ATTR_MAXELEM] = { .name = "MAXELEM" }, - [IPSET_ATTR_NETMASK] = { .name = "NETMASK" }, - [IPSET_ATTR_PROBES] = { .name = "PROBES" }, - [IPSET_ATTR_RESIZE] = { .name = "RESIZE" }, - [IPSET_ATTR_SIZE] = { .name = "SIZE" }, - [IPSET_ATTR_ELEMENTS] = { .name = "ELEMENTS" }, - [IPSET_ATTR_REFERENCES] = { .name = "REFERENCES" }, - [IPSET_ATTR_MEMSIZE] = { .name = "MEMSIZE" }, -}; - -static const struct ipset_attrname adtattr2name[] = { - [IPSET_ATTR_IP] = { .name = "IP" }, - [IPSET_ATTR_IP_TO] = { .name = "IP_TO" }, - [IPSET_ATTR_CIDR] = { .name = "CIDR" }, - [IPSET_ATTR_PORT] = { .name = "PORT" }, - [IPSET_ATTR_PORT_TO] = { .name = "PORT_TO" }, - [IPSET_ATTR_TIMEOUT] = { .name = "TIMEOUT" }, - [IPSET_ATTR_PROTO] = { .name = "PROTO" }, - [IPSET_ATTR_CADT_FLAGS] = { .name = "CADT_FLAGS" }, - [IPSET_ATTR_CADT_LINENO] = { .name = "CADT_LINENO" }, - [IPSET_ATTR_ETHER] = { .name = "ETHER" }, - [IPSET_ATTR_NAME] = { .name = "NAME" }, - [IPSET_ATTR_NAMEREF] = { .name = "NAMEREF" }, - [IPSET_ATTR_IP2] = { .name = "IP2" }, - [IPSET_ATTR_CIDR2] = { .name = "CIDR2" }, - [IPSET_ATTR_IP2_TO] = { .name = "IP2_TO" }, - [IPSET_ATTR_IFACE] = { .name = "IFACE" }, -}; - -static void -debug_cadt_attrs(int max, const struct ipset_attr_policy *policy, - const struct ipset_attrname attr2name[], - struct nlattr *nla[]) -{ - uint32_t v; - int i; - - fprintf(stderr, "\t\t%s attributes:\n", - policy == create_attrs ? "CREATE" : "ADT"); - for (i = IPSET_ATTR_UNSPEC + 1; i <= max; i++) { - if (!nla[i]) - continue; - switch (policy[i].type) { - case MNL_TYPE_U8: - v = *(uint8_t *) mnl_attr_get_payload(nla[i]); - fprintf(stderr, "\t\t%s: %u\n", - attr2name[i].name, v); - break; - case MNL_TYPE_U16: - v = *(uint16_t *) mnl_attr_get_payload(nla[i]); - fprintf(stderr, "\t\t%s: %u\n", - attr2name[i].name, ntohs(v)); - break; - case MNL_TYPE_U32: - v = *(uint32_t *) mnl_attr_get_payload(nla[i]); - fprintf(stderr, "\t\t%s: %u\n", - attr2name[i].name, ntohl(v)); - break; - case MNL_TYPE_NUL_STRING: - fprintf(stderr, "\t\t%s: %s\n", - attr2name[i].name, - (const char *) mnl_attr_get_payload(nla[i])); - break; - case MNL_TYPE_NESTED: { - struct nlattr *ipattr[IPSET_ATTR_IPADDR_MAX+1] = {}; - char addr[INET6_ADDRSTRLEN]; - void *d; - - if (mnl_attr_parse_nested(nla[i], ipaddr_attr_cb, - ipattr) < 0) { - fprintf(stderr, - "\t\tIPADDR: cannot validate " - "and parse attributes\n"); - continue; - } - if (ipattr[IPSET_ATTR_IPADDR_IPV4]) { - d = mnl_attr_get_payload( - ipattr[IPSET_ATTR_IPADDR_IPV4]); - - inet_ntop(NFPROTO_IPV4, d, addr, INET6_ADDRSTRLEN); - fprintf(stderr, "\t\t%s: %s\n", - attr2name[i].name, addr); - } else if (ipattr[IPSET_ATTR_IPADDR_IPV6]) { - d = mnl_attr_get_payload( - ipattr[IPSET_ATTR_IPADDR_IPV6]); - - inet_ntop(NFPROTO_IPV6, d, addr, INET6_ADDRSTRLEN); - fprintf(stderr, "\t\t%s: %s\n", - attr2name[i].name, addr); - } - break; - } - default: - fprintf(stderr, "\t\t%s: unresolved!\n", - attr2name[i].name); - } - } -} - -static void -debug_cmd_attrs(int cmd, struct nlattr *nla[]) -{ - struct nlattr *adt[IPSET_ATTR_ADT_MAX+1] = {}; - struct nlattr *cattr[IPSET_ATTR_CREATE_MAX+1] = {}; - uint32_t v; - int i; - - fprintf(stderr, "\tCommand attributes:\n"); - for (i = IPSET_ATTR_UNSPEC + 1; i <= IPSET_ATTR_CMD_MAX; i++) { - if (!nla[i]) - continue; - switch (cmd_attrs[i].type) { - case MNL_TYPE_U8: - v = *(uint8_t *) mnl_attr_get_payload(nla[i]); - fprintf(stderr, "\t%s: %u\n", - cmdattr2name[i].name, v); - break; - case MNL_TYPE_U16: - v = *(uint16_t *) mnl_attr_get_payload(nla[i]); - fprintf(stderr, "\t%s: %u\n", - cmdattr2name[i].name, ntohs(v)); - break; - case MNL_TYPE_U32: - v = *(uint32_t *) mnl_attr_get_payload(nla[i]); - fprintf(stderr, "\t%s: %u\n", - cmdattr2name[i].name, ntohl(v)); - break; - case MNL_TYPE_NUL_STRING: - fprintf(stderr, "\t%s: %s\n", - cmdattr2name[i].name, - (const char *) mnl_attr_get_payload(nla[i])); - break; - case MNL_TYPE_NESTED: - if (i == IPSET_ATTR_DATA) { - switch (cmd) { - case IPSET_CMD_ADD: - case IPSET_CMD_DEL: - case IPSET_CMD_TEST: - if (mnl_attr_parse_nested(nla[i], - adt_attr_cb, adt) < 0) { - fprintf(stderr, - "\tADT: cannot validate " - "and parse attributes\n"); - continue; - } - debug_cadt_attrs(IPSET_ATTR_ADT_MAX, - adt_attrs, - adtattr2name, - adt); - break; - default: - if (mnl_attr_parse_nested(nla[i], - create_attr_cb, - cattr) < 0) { - fprintf(stderr, - "\tCREATE: cannot validate " - "and parse attributes\n"); - continue; - } - debug_cadt_attrs(IPSET_ATTR_CREATE_MAX, - create_attrs, - createattr2name, - cattr); - } - } else { - struct nlattr *tb; - mnl_attr_for_each_nested(tb, nla[i]) { - memset(adt, 0, sizeof(adt)); - if (mnl_attr_parse_nested(tb, - adt_attr_cb, adt) < 0) { - fprintf(stderr, - "\tADT: cannot validate " - "and parse attributes\n"); - continue; - } - debug_cadt_attrs(IPSET_ATTR_ADT_MAX, - adt_attrs, - adtattr2name, - adt); - } - } - break; - default: - fprintf(stderr, "\t%s: unresolved!\n", - cmdattr2name[i].name); - } - } -} - -void -ipset_debug_msg(const char *dir, void *buffer, int len) -{ - const struct nlmsghdr *nlh = buffer; - struct nlattr *nla[IPSET_ATTR_CMD_MAX+1] = {}; - int cmd, nfmsglen = MNL_ALIGN(sizeof(struct nfgenmsg)); - - debug = 0; - while (mnl_nlmsg_ok(nlh, len)) { - switch (nlh->nlmsg_type) { - case NLMSG_NOOP: - case NLMSG_DONE: - case NLMSG_OVERRUN: - fprintf(stderr, "Message header: %s msg %s\n" - "\tlen %d\n" - "\tseq %u\n", - dir, - nlh->nlmsg_type == NLMSG_NOOP ? "NOOP" : - nlh->nlmsg_type == NLMSG_DONE ? "DONE" : - "OVERRUN", - len, nlh->nlmsg_seq); - goto next_msg; - case NLMSG_ERROR: { - const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh); - fprintf(stderr, "Message header: %s msg ERROR\n" - "\tlen %d\n" - "\terrcode %d\n" - "\tseq %u\n", - dir, len, err->error, nlh->nlmsg_seq); - goto next_msg; - } - default: - ; - } - cmd = ipset_get_nlmsg_type(nlh); - fprintf(stderr, "Message header: %s cmd %s (%d)\n" - "\tlen %d\n" - "\tflag %s\n" - "\tseq %u\n", - dir, - cmd <= IPSET_CMD_NONE ? "NONE!" : - cmd >= IPSET_CMD_MAX ? "MAX!" : cmd2name[cmd], cmd, - len, - !(nlh->nlmsg_flags & NLM_F_EXCL) ? "EXIST" : "none", - nlh->nlmsg_seq); - if (cmd <= IPSET_CMD_NONE || cmd >= IPSET_CMD_MAX) - goto next_msg; - memset(nla, 0, sizeof(nla)); - if (mnl_attr_parse(nlh, nfmsglen, - cmd_attr_cb, nla) < MNL_CB_STOP) { - fprintf(stderr, "\tcannot validate " - "and parse attributes\n"); - goto next_msg; - } - debug_cmd_attrs(cmd, nla); -next_msg: - nlh = mnl_nlmsg_next(nlh, &len); - } - debug = 1; -} diff --git a/extensions/ipset-6/libipset/errcode.c b/extensions/ipset-6/libipset/errcode.c deleted file mode 100644 index 1ce5c00..0000000 --- a/extensions/ipset-6/libipset/errcode.c +++ /dev/null @@ -1,200 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* assert */ -#include /* errno */ -#include /* strerror */ - -#include /* D() */ -#include /* ipset_data_get */ -#include /* ipset_err */ -#include /* struct ipset_type */ -#include /* STRNEQ */ -#include /* prototypes */ -#include /* bitmap specific errcodes */ -#include /* hash specific errcodes */ -#include /* list specific errcodes */ - -/* Core kernel error codes */ -static const struct ipset_errcode_table core_errcode_table[] = { - /* Generic error codes */ - { ENOENT, 0, - "The set with the given name does not exist" }, - { EMSGSIZE, 0, - "Kernel error received: message could not be created" }, - { IPSET_ERR_PROTOCOL, 0, - "Kernel error received: ipset protocol error" }, - - /* CREATE specific error codes */ - { EEXIST, IPSET_CMD_CREATE, - "Set cannot be created: set with the same name already exists" }, - { IPSET_ERR_FIND_TYPE, 0, - "Kernel error received: set type not supported" }, - { IPSET_ERR_MAX_SETS, 0, - "Kernel error received: maximal number of sets reached, " - "cannot create more." }, - { IPSET_ERR_INVALID_NETMASK, 0, - "The value of the netmask parameter is invalid" }, - { IPSET_ERR_INVALID_FAMILY, 0, - "Protocol family not supported by the set type" }, - - /* DESTROY specific error codes */ - { IPSET_ERR_BUSY, IPSET_CMD_DESTROY, - "Set cannot be destroyed: it is in use by a kernel component" }, - - /* FLUSH specific error codes */ - - /* RENAME specific error codes */ - { IPSET_ERR_EXIST_SETNAME2, IPSET_CMD_RENAME, - "Set cannot be renamed: a set with the new name already exists" }, - { IPSET_ERR_REFERENCED, IPSET_CMD_RENAME, - "Set cannot be renamed: it is in use by another system" }, - - /* SWAP specific error codes */ - { IPSET_ERR_EXIST_SETNAME2, IPSET_CMD_SWAP, - "Sets cannot be swapped: the second set does not exist" }, - { IPSET_ERR_TYPE_MISMATCH, IPSET_CMD_SWAP, - "The sets cannot be swapped: they type does not match" }, - - /* LIST/SAVE specific error codes */ - - /* Generic (CADT) error codes */ - { IPSET_ERR_INVALID_CIDR, 0, - "The value of the CIDR parameter of the IP address is invalid" }, - { IPSET_ERR_TIMEOUT, 0, - "Timeout cannot be used: set was created without timeout support" }, - { IPSET_ERR_IPADDR_IPV4, 0, - "An IPv4 address is expected, but not received" }, - { IPSET_ERR_IPADDR_IPV6, 0, - "An IPv6 address is expected, but not received" }, - - /* ADD specific error codes */ - { IPSET_ERR_EXIST, IPSET_CMD_ADD, - "Element cannot be added to the set: it's already added" }, - - /* DEL specific error codes */ - { IPSET_ERR_EXIST, IPSET_CMD_DEL, - "Element cannot be deleted from the set: it's not added" }, - - /* TEST specific error codes */ - - /* HEADER specific error codes */ - - /* TYPE specific error codes */ - { EEXIST, IPSET_CMD_TYPE, - "Kernel error received: set type does not supported" }, - - /* PROTOCOL specific error codes */ - - { }, -}; - -/* Bitmap type-specific error codes */ -static const struct ipset_errcode_table bitmap_errcode_table[] = { - /* Generic (CADT) error codes */ - { IPSET_ERR_BITMAP_RANGE, 0, - "Element is out of the range of the set" }, - { IPSET_ERR_BITMAP_RANGE_SIZE, IPSET_CMD_CREATE, - "The range you specified exceeds the size limit of the set type" }, - { }, -}; - -/* Hash type-specific error codes */ -static const struct ipset_errcode_table hash_errcode_table[] = { - /* Generic (CADT) error codes */ - { IPSET_ERR_HASH_FULL, 0, - "Hash is full, cannot add more elements" }, - { IPSET_ERR_HASH_ELEM, 0, - "Null-valued element, cannot be stored in a hash type of set" }, - { IPSET_ERR_INVALID_PROTO, 0, - "Invalid protocol specified" }, - { IPSET_ERR_MISSING_PROTO, 0, - "Protocol missing, but must be specified" }, - { IPSET_ERR_HASH_RANGE_UNSUPPORTED, 0, - "Range is not supported in the \"net\" component of the element" }, - { IPSET_ERR_HASH_RANGE, 0, - "Invalid range, covers the whole address space" }, - { }, -}; - -/* List type-specific error codes */ -static const struct ipset_errcode_table list_errcode_table[] = { - /* Generic (CADT) error codes */ - { IPSET_ERR_NAME, 0, - "Set to be added/deleted/tested as element does not exist." }, - { IPSET_ERR_LOOP, 0, - "Sets with list:set type cannot be added to the set." }, - { IPSET_ERR_BEFORE, 0, - "No reference set specified." }, - { IPSET_ERR_NAMEREF, 0, - "The set to which you referred with 'before' or 'after' " - "does not exist." }, - { IPSET_ERR_LIST_FULL, 0, - "The set is full, more elements cannot be added." }, - { IPSET_ERR_REF_EXIST, 0, - "The set to which you referred with 'before' or 'after' " - "is not added to the set." }, - { }, -}; - -#define MATCH_TYPENAME(a, b) STRNEQ(a, b, strlen(b)) - -/** - * ipset_errcode - interpret a kernel error code - * @session: session structure - * @errcode: errcode - * - * Find the error code and print the appropriate - * error message into the error buffer. - * - * Returns -1. - */ -int -ipset_errcode(struct ipset_session *session, enum ipset_cmd cmd, int errcode) -{ - const struct ipset_errcode_table *table = core_errcode_table; - int i, generic; - - if (errcode >= IPSET_ERR_TYPE_SPECIFIC) { - const struct ipset_type *type; - - type = ipset_saved_type(session); - if (type) { - if (MATCH_TYPENAME(type->name, "bitmap:")) - table = bitmap_errcode_table; - else if (MATCH_TYPENAME(type->name, "hash:")) - table = hash_errcode_table; - else if (MATCH_TYPENAME(type->name, "list:")) - table = list_errcode_table; - } - } - -retry: - for (i = 0, generic = -1; table[i].errcode; i++) { - if (table[i].errcode == errcode && - (table[i].cmd == cmd || table[i].cmd == 0)) { - if (table[i].cmd == 0) { - generic = i; - continue; - } - return ipset_err(session, table[i].message); - } - } - if (generic != -1) - return ipset_err(session, table[generic].message); - /* Fall back to the core table */ - if (table != core_errcode_table) { - table = core_errcode_table; - goto retry; - } - if (errcode < IPSET_ERR_PRIVATE) - return ipset_err(session, "Kernel error received: %s", - strerror(errcode)); - else - return ipset_err(session, - "Undecoded error %u received from kernel", - errcode); -} diff --git a/extensions/ipset-6/libipset/icmp.c b/extensions/ipset-6/libipset/icmp.c deleted file mode 100644 index c50be7e..0000000 --- a/extensions/ipset-6/libipset/icmp.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* STRNEQ */ -#include /* prototypes */ - -struct icmp_names { - const char *name; - uint8_t type, code; -}; - -static const struct icmp_names icmp_typecodes[] = { - { "echo-reply", 0, 0 }, - { "pong", 0, 0 }, - { "network-unreachable", 3, 0 }, - { "host-unreachable", 3, 1 }, - { "protocol-unreachable", 3, 2 }, - { "port-unreachable", 3, 3 }, - { "fragmentation-needed", 3, 4 }, - { "source-route-failed", 3, 5 }, - { "network-unknown", 3, 6 }, - { "host-unknown", 3, 7 }, - { "network-prohibited", 3, 9 }, - { "host-prohibited", 3, 10 }, - { "TOS-network-unreachable", 3, 11 }, - { "TOS-host-unreachable", 3, 12 }, - { "communication-prohibited", 3, 13 }, - { "host-precedence-violation", 3, 14 }, - { "precedence-cutoff", 3, 15 }, - { "source-quench", 4, 0 }, - { "network-redirect", 5, 0 }, - { "host-redirect", 5, 1 }, - { "TOS-network-redirect", 5, 2 }, - { "TOS-host-redirect", 5, 3 }, - { "echo-request", 8, 0 }, - { "ping", 8, 0 }, - { "router-advertisement", 9, 0 }, - { "router-solicitation", 10, 0 }, - { "ttl-zero-during-transit", 11, 0 }, - { "ttl-zero-during-reassembly", 11, 1 }, - { "ip-header-bad", 12, 0 }, - { "required-option-missing", 12, 1 }, - { "timestamp-request", 13, 0 }, - { "timestamp-reply", 14, 0 }, - { "address-mask-request", 17, 0 }, - { "address-mask-reply", 18, 0 }, -}; - -const char *id_to_icmp(uint8_t id) -{ - return id < ARRAY_SIZE(icmp_typecodes) ? icmp_typecodes[id].name : NULL; -} - -const char *icmp_to_name(uint8_t type, uint8_t code) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(icmp_typecodes); i++) - if (icmp_typecodes[i].type == type && - icmp_typecodes[i].code == code) - return icmp_typecodes[i].name; - - return NULL; -} - -int name_to_icmp(const char *str, uint16_t *typecode) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(icmp_typecodes); i++) - if (STRNCASEQ(icmp_typecodes[i].name, str, strlen(str))) { - *typecode = (icmp_typecodes[i].type << 8) | - icmp_typecodes[i].code; - return 0; - } - - return -1; -} diff --git a/extensions/ipset-6/libipset/icmpv6.c b/extensions/ipset-6/libipset/icmpv6.c deleted file mode 100644 index 82234da..0000000 --- a/extensions/ipset-6/libipset/icmpv6.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* STRNEQ */ -#include /* prototypes */ - -struct icmpv6_names { - const char *name; - uint8_t type, code; -}; - -static const struct icmpv6_names icmpv6_typecodes[] = { - { "no-route", 1, 0 }, - { "communication-prohibited", 1, 1 }, - { "address-unreachable", 1, 3 }, - { "port-unreachable", 1, 4 }, - { "packet-too-big", 2, 0 }, - { "ttl-zero-during-transit", 3, 0 }, - { "ttl-zero-during-reassembly", 3, 1 }, - { "bad-header", 4, 0 }, - { "unknown-header-type", 4, 1 }, - { "unknown-option", 4, 2 }, - { "echo-request", 128, 0 }, - { "ping", 128, 0 }, - { "echo-reply", 129, 0 }, - { "pong", 129, 0 }, - { "router-solicitation", 133, 0 }, - { "router-advertisement", 134, 0 }, - { "neighbour-solicitation", 135, 0 }, - { "neigbour-solicitation", 135, 0 }, - { "neighbour-advertisement", 136, 0 }, - { "neigbour-advertisement", 136, 0 }, - { "redirect", 137, 0 }, -}; - -const char *id_to_icmpv6(uint8_t id) -{ - return id < ARRAY_SIZE(icmpv6_typecodes) ? - icmpv6_typecodes[id].name : NULL; -} - -const char *icmpv6_to_name(uint8_t type, uint8_t code) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(icmpv6_typecodes); i++) - if (icmpv6_typecodes[i].type == type && - icmpv6_typecodes[i].code == code) - return icmpv6_typecodes[i].name; - - return NULL; -} - -int name_to_icmpv6(const char *str, uint16_t *typecode) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(icmpv6_typecodes); i++) - if (STRNCASEQ(icmpv6_typecodes[i].name, str, strlen(str))) { - *typecode = (icmpv6_typecodes[i].type << 8) | - icmpv6_typecodes[i].code; - return 0; - } - - return -1; -} diff --git a/extensions/ipset-6/libipset/mnl.c b/extensions/ipset-6/libipset/mnl.c deleted file mode 100644 index 4ad51ac..0000000 --- a/extensions/ipset-6/libipset/mnl.c +++ /dev/null @@ -1,264 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* assert */ -#include /* errno */ -#include -#include /* calloc, free */ -#include /* time */ -#include /* hto* */ - -#include /* enum ipset_cmd */ -#include /* D() */ -#include /* ipset_session_handle */ -#include /* IPSET_ENV_EXIST */ -#include /* UNUSED */ -#include /* prototypes */ - -#include -#include -#include - -#ifndef NFNL_SUBSYS_IPSET -#define NFNL_SUBSYS_IPSET 6 -#endif - -/* Internal data structure for the kernel-userspace communication parameters */ -struct ipset_handle { - struct mnl_socket *h; /* the mnl socket */ - unsigned int seq; /* netlink message sequence number */ - unsigned int portid; /* the socket port identifier */ - mnl_cb_t *cb_ctl; /* control block callbacks */ - void *data; /* data pointer */ - unsigned int genl_id; /* genetlink ID of ip_set */ -}; - -/* Netlink flags of the commands */ -static const uint16_t cmdflags[] = { - [IPSET_CMD_CREATE-1] = NLM_F_REQUEST|NLM_F_ACK| - NLM_F_CREATE|NLM_F_EXCL, - [IPSET_CMD_DESTROY-1] = NLM_F_REQUEST|NLM_F_ACK, - [IPSET_CMD_FLUSH-1] = NLM_F_REQUEST|NLM_F_ACK, - [IPSET_CMD_RENAME-1] = NLM_F_REQUEST|NLM_F_ACK, - [IPSET_CMD_SWAP-1] = NLM_F_REQUEST|NLM_F_ACK, - [IPSET_CMD_LIST-1] = NLM_F_REQUEST|NLM_F_ACK, - [IPSET_CMD_SAVE-1] = NLM_F_REQUEST|NLM_F_ACK, - [IPSET_CMD_ADD-1] = NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL, - [IPSET_CMD_DEL-1] = NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL, - [IPSET_CMD_TEST-1] = NLM_F_REQUEST|NLM_F_ACK, - [IPSET_CMD_HEADER-1] = NLM_F_REQUEST, - [IPSET_CMD_TYPE-1] = NLM_F_REQUEST, - [IPSET_CMD_PROTOCOL-1] = NLM_F_REQUEST, -}; - -/** - * ipset_get_nlmsg_type - get ipset netlink message type - * @nlh: pointer to the netlink message header - * - * Returns the ipset netlink message type, i.e. the ipset command. - */ -int -ipset_get_nlmsg_type(const struct nlmsghdr *nlh) -{ - const struct genlmsghdr *ghdr = mnl_nlmsg_get_payload(nlh); - - return ghdr->cmd; -} - -static void -ipset_mnl_fill_hdr(struct ipset_handle *handle, enum ipset_cmd cmd, - void *buffer, size_t len UNUSED, uint8_t envflags) -{ - struct nlmsghdr *nlh; - struct genlmsghdr *ghdr; - - assert(handle); - assert(buffer); - assert(cmd > IPSET_CMD_NONE && cmd < IPSET_MSG_MAX); - - nlh = mnl_nlmsg_put_header(buffer); - nlh->nlmsg_type = handle->genl_id; - nlh->nlmsg_flags = NLM_F_REQUEST; - if (cmdflags[cmd-1] & NLM_F_ACK) - nlh->nlmsg_flags |= NLM_F_ACK; - - ghdr = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr)); - ghdr->cmd = cmd; - /* (ge)netlink is dumb, NLM_F_CREATE and NLM_F_DUMP overlap, get misinterpreted. */ - ghdr->reserved = cmdflags[cmd-1]; - if (envflags & IPSET_ENV_EXIST) - ghdr->reserved &= ~NLM_F_EXCL; -} - -static int -ipset_mnl_query(struct ipset_handle *handle, void *buffer, size_t len) -{ - struct nlmsghdr *nlh = buffer; - int ret; - - assert(handle); - assert(buffer); - - nlh->nlmsg_seq = ++handle->seq; -#ifdef IPSET_DEBUG - ipset_debug_msg("sent", nlh, nlh->nlmsg_len); -#endif - if (mnl_socket_sendto(handle->h, nlh, nlh->nlmsg_len) < 0) - return -ECOMM; - - ret = mnl_socket_recvfrom(handle->h, buffer, len); -#ifdef IPSET_DEBUG - ipset_debug_msg("received", buffer, ret); -#endif - while (ret > 0) { - ret = mnl_cb_run2(buffer, ret, - handle->seq, handle->portid, - handle->cb_ctl[NLMSG_MIN_TYPE], - handle->data, - handle->cb_ctl, NLMSG_MIN_TYPE); - D("nfln_cb_run2, ret: %d, errno %d", ret, errno); - if (ret <= 0) - break; - ret = mnl_socket_recvfrom(handle->h, buffer, len); - D("message received, ret: %d", ret); - } - return ret > 0 ? 0 : ret; -} - -static int ipset_mnl_getid_acb(const struct nlattr *attr, void *datap) -{ - const struct nlattr **tb = datap; - uint16_t type = mnl_attr_get_type(attr); - - if (mnl_attr_type_valid(attr, CTRL_ATTR_MAX) < 0) - return MNL_CB_OK; - tb[type] = attr; - return MNL_CB_OK; -} - -static int ipset_mnl_getid_cb(const struct nlmsghdr *nlhdr, void *datap) -{ - struct ipset_handle *h = datap; - const struct nlattr *tb[CTRL_ATTR_MAX+1] = {0}; - const struct genlmsghdr *ghdr = mnl_nlmsg_get_payload(nlhdr); - int ret; - - ret = mnl_attr_parse(nlhdr, sizeof(*ghdr), ipset_mnl_getid_acb, tb); - if (ret != MNL_CB_OK) - return ret; - if (tb[CTRL_ATTR_FAMILY_ID] != NULL) - h->genl_id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]); - return MNL_CB_OK; -} - -/** - * Look up the GENL identifier for the ip_set subsystem, and store it in - * @h->genl_id. On success, 0 is returned, otherwise error encoded as - * negative number. - */ -static int ipset_mnl_getid(struct ipset_handle *h, bool modprobe) -{ - size_t buf_size = 8192; //MNL_SOCKET_BUFFER_SIZE; - struct nlmsghdr *nlhdr; - struct genlmsghdr *ghdr; - char *buf; - int ret = -ENOENT; - - h->genl_id = 0; - - if (modprobe) { - /* genetlink has no autoloading like nfnetlink... */ - system("/sbin/modprobe -q ip_set"); - } - - buf = malloc(buf_size); - if (buf == NULL) - return -errno; - - nlhdr = mnl_nlmsg_put_header(buf); - nlhdr->nlmsg_type = GENL_ID_CTRL; - nlhdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - ghdr = mnl_nlmsg_put_extra_header(nlhdr, sizeof(struct genlmsghdr)); - ghdr->cmd = CTRL_CMD_GETFAMILY; - ghdr->version = 2; - if (!mnl_attr_put_strz_check(nlhdr, buf_size, - CTRL_ATTR_FAMILY_NAME, "ip_set")) - goto out; - - ret = mnl_socket_sendto(h->h, buf, nlhdr->nlmsg_len); - if (ret < 0) - goto out; - ret = mnl_socket_recvfrom(h->h, buf, buf_size); - while (ret > 0) { - ret = mnl_cb_run(buf, ret, 0, 0, ipset_mnl_getid_cb, h); - if (ret <= 0) - break; - ret = mnl_socket_recvfrom(h->h, buf, buf_size); - } - if (h->genl_id == 0 && !modprobe) - /* Redo, with modprobe this time. */ - ret = ipset_mnl_getid(h, true); - if (h->genl_id > 0) - ret = 0; - out: - free(buf); - return ret; -} - -static struct ipset_handle * -ipset_mnl_init(mnl_cb_t *cb_ctl, void *data) -{ - struct ipset_handle *handle; - - assert(cb_ctl); - assert(data); - - handle = calloc(1, sizeof(*handle)); - if (!handle) - return NULL; - - handle->h = mnl_socket_open(NETLINK_GENERIC); - if (!handle->h) - goto free_handle; - - if (mnl_socket_bind(handle->h, 0, MNL_SOCKET_AUTOPID) < 0) - goto close_nl; - - handle->portid = mnl_socket_get_portid(handle->h); - handle->cb_ctl = cb_ctl; - handle->data = data; - handle->seq = time(NULL); - - if (ipset_mnl_getid(handle, false) < 0) - goto close_nl; - return handle; - -close_nl: - mnl_socket_close(handle->h); -free_handle: - free(handle); - - return NULL; -} - -static int -ipset_mnl_fini(struct ipset_handle *handle) -{ - assert(handle); - - if (handle->h) - mnl_socket_close(handle->h); - - free(handle); - return 0; -} - -const struct ipset_transport ipset_mnl_transport = { - .init = ipset_mnl_init, - .fini = ipset_mnl_fini, - .fill_hdr = ipset_mnl_fill_hdr, - .query = ipset_mnl_query, -}; diff --git a/extensions/ipset-6/libipset/parse.c b/extensions/ipset-6/libipset/parse.c deleted file mode 100644 index eeb253c..0000000 --- a/extensions/ipset-6/libipset/parse.c +++ /dev/null @@ -1,1631 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* assert */ -#include /* errno */ -#include /* ULLONG_MAX */ -#include /* getservbyname, getaddrinfo */ -#include /* strtoull, etc. */ -#include /* getaddrinfo */ -#include /* getaddrinfo, AF_ */ -#include /* ETH_ALEN */ -#include /* IFNAMSIZ */ -#include /* IPPROTO_ */ - -#include /* D() */ -#include /* IPSET_OPT_* */ -#include /* name_to_icmp */ -#include /* name_to_icmpv6 */ -#include /* prefixlen_netmask_map */ -#include /* ipset_err */ -#include /* ipset_type_get */ -#include /* string utilities */ -#include /* prototypes */ - -#ifndef ULLONG_MAX -#define ULLONG_MAX 18446744073709551615ULL -#endif - -/* Parse input data */ - -#define cidr_separator(str) ipset_strchr(str, IPSET_CIDR_SEPARATOR) -#define range_separator(str) ipset_strchr(str, IPSET_RANGE_SEPARATOR) -#define elem_separator(str) ipset_strchr(str, IPSET_ELEM_SEPARATOR) -#define name_separator(str) ipset_strchr(str, IPSET_NAME_SEPARATOR) -#define proto_separator(str) ipset_strchr(str, IPSET_PROTO_SEPARATOR) - -#define syntax_err(fmt, args...) \ - ipset_err(session, "Syntax error: " fmt , ## args) - -static char * -ipset_strchr(const char *str, const char *sep) -{ - char *match; - - assert(str); - assert(sep); - - for (; *sep != '\0'; sep++) { - match = strchr(str, sep[0]); - if (match != NULL && - str[0] != sep[0] && - str[strlen(str)-1] != sep[0]) - return match; - } - - return NULL; -} - -/* - * Parser functions, shamelessly taken from iptables.c, ip6tables.c - * and parser.c from libnetfilter_conntrack. - */ - -/* - * Parse numbers - */ -static int -string_to_number_ll(struct ipset_session *session, - const char *str, - unsigned long long min, - unsigned long long max, - unsigned long long *ret) -{ - unsigned long long number = 0; - char *end; - - /* Handle hex, octal, etc. */ - errno = 0; - number = strtoull(str, &end, 0); - if (*end == '\0' && end != str && errno != ERANGE) { - /* we parsed a number, let's see if we want this */ - if (min <= number && (!max || number <= max)) { - *ret = number; - return 0; - } else - errno = ERANGE; - } - if (errno == ERANGE && max) - return syntax_err("'%s' is out of range %llu-%llu", - str, min, max); - else if (errno == ERANGE) - return syntax_err("'%s' is out of range %llu-%llu", - str, min, ULLONG_MAX); - else - return syntax_err("'%s' is invalid as number", str); -} - -static int -string_to_u8(struct ipset_session *session, - const char *str, uint8_t *ret) -{ - int err; - unsigned long long num = 0; - - err = string_to_number_ll(session, str, 0, 255, &num); - *ret = num; - - return err; -} - -static int -string_to_cidr(struct ipset_session *session, - const char *str, uint8_t min, uint8_t max, uint8_t *ret) -{ - int err = string_to_u8(session, str, ret); - - if (!err && (*ret < min || *ret > max)) - return syntax_err("'%s' is out of range %u-%u", - str, min, max); - - return err; -} - -static int -string_to_u16(struct ipset_session *session, - const char *str, uint16_t *ret) -{ - int err; - unsigned long long num = 0; - - err = string_to_number_ll(session, str, 0, USHRT_MAX, &num); - *ret = num; - - return err; -} - -static int -string_to_u32(struct ipset_session *session, - const char *str, uint32_t *ret) -{ - int err; - unsigned long long num = 0; - - err = string_to_number_ll(session, str, 0, UINT_MAX, &num); - *ret = num; - - return err; -} - -/** - * ipset_parse_ether - parse ethernet address - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an ethernet address. The parsed ethernet - * address is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_ether(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - unsigned int i = 0; - unsigned char ether[ETH_ALEN]; - - assert(session); - assert(opt == IPSET_OPT_ETHER); - assert(str); - - if (strlen(str) != ETH_ALEN * 3 - 1) - goto error; - - for (i = 0; i < ETH_ALEN; i++) { - long number; - char *end; - - number = strtol(str + i * 3, &end, 16); - - if (end == str + i * 3 + 2 && - (*end == ':' || *end == '\0') && - number >= 0 && number <= 255) - ether[i] = number; - else - goto error; - } - return ipset_session_data_set(session, opt, ether); - -error: - return syntax_err("cannot parse '%s' as ethernet address", str); -} - -/* - * Parse TCP service names or port numbers - */ -static int -parse_portname(struct ipset_session *session, const char *str, - uint16_t *port, const char *proto) -{ - struct servent *service = getservbyname(str, proto); - - if (service != NULL) { - *port = ntohs((uint16_t) service->s_port); - return 0; - } - - return syntax_err("cannot parse '%s' as a %s port", str, proto); -} - -/** - * ipset_parse_single_port - parse a single port number or name - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * @proto: protocol - * - * Parse string as a single port number or name. The parsed port - * number is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_port(struct ipset_session *session, - enum ipset_opt opt, const char *str, - const char *proto) -{ - uint16_t port; - int err; - - assert(session); - assert(opt == IPSET_OPT_PORT || opt == IPSET_OPT_PORT_TO); - assert(str); - - if ((err = string_to_u16(session, str, &port)) == 0 || - (err = parse_portname(session, str, &port, proto)) == 0) - err = ipset_session_data_set(session, opt, &port); - - if (!err) - /* No error, so reset false error messages! */ - ipset_session_report_reset(session); - - return err; -} - -/** - * ipset_parse_tcpudp_port - parse TCP/UDP port name, number, or range of them - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * @proto: TCP|UDP - * - * Parse string as a TCP/UDP port name or number or range of them - * separated by a dash. The parsed port numbers are stored - * in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_tcpudp_port(struct ipset_session *session, - enum ipset_opt opt, const char *str, const char *proto) -{ - char *a, *saved, *tmp; - int err = 0; - - assert(session); - assert(opt == IPSET_OPT_PORT); - assert(str); - - saved = tmp = strdup(str); - if (tmp == NULL) - return ipset_err(session, - "Cannot allocate memory to duplicate %s.", - str); - - a = range_separator(tmp); - if (a != NULL) { - /* port-port */ - *a++ = '\0'; - err = ipset_parse_port(session, IPSET_OPT_PORT_TO, a, proto); - if (err) - goto error; - } - err = ipset_parse_port(session, opt, tmp, proto); - -error: - free(saved); - return err; -} - -/** - * ipset_parse_tcp_port - parse TCP port name, number, or range of them - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as a TCP port name or number or range of them - * separated by a dash. The parsed port numbers are stored - * in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_tcp_port(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - return ipset_parse_tcpudp_port(session, opt, str, "tcp"); -} - -/** - * ipset_parse_single_tcp_port - parse TCP port name or number - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as a single TCP port name or number. - * The parsed port number is stored - * in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_single_tcp_port(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - assert(session); - assert(opt == IPSET_OPT_PORT || opt == IPSET_OPT_PORT_TO); - assert(str); - - return ipset_parse_port(session, opt, str, "tcp"); -} - -/** - * ipset_parse_proto - parse protocol name - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as a protocol name. - * The parsed protocol is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_proto(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - const struct protoent *protoent; - uint8_t proto = 0; - - assert(session); - assert(opt == IPSET_OPT_PROTO); - assert(str); - - protoent = getprotobyname(strcasecmp(str, "icmpv6") == 0 - ? "ipv6-icmp" : str); - if (protoent == NULL) - return syntax_err("cannot parse '%s' " - "as a protocol name", str); - proto = protoent->p_proto; - if (!proto) - return syntax_err("Unsupported protocol '%s'", str); - - return ipset_session_data_set(session, opt, &proto); -} - -/* Parse ICMP and ICMPv6 type/code */ -static int -parse_icmp_typecode(struct ipset_session *session, - enum ipset_opt opt, const char *str, - const char *family) -{ - uint16_t typecode; - uint8_t type, code; - char *a, *saved, *tmp; - int err; - - saved = tmp = strdup(str); - if (tmp == NULL) - return ipset_err(session, - "Cannot allocate memory to duplicate %s.", - str); - a = cidr_separator(tmp); - if (a == NULL) { - free(saved); - return ipset_err(session, - "Cannot parse %s as an %s type/code.", - str, family); - } - *a++ = '\0'; - if ((err = string_to_u8(session, tmp, &type)) != 0 || - (err = string_to_u8(session, a, &code)) != 0) - goto error; - - typecode = (type << 8) | code; - err = ipset_session_data_set(session, opt, &typecode); - -error: - free(saved); - return err; -} - -/** - * ipset_parse_icmp - parse an ICMP name or type/code - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an ICMP name or type/code numbers. - * The parsed ICMP type/code is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_icmp(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - uint16_t typecode; - - assert(session); - assert(opt == IPSET_OPT_PORT); - assert(str); - - if (name_to_icmp(str, &typecode) < 0) - return parse_icmp_typecode(session, opt, str, "ICMP"); - - return ipset_session_data_set(session, opt, &typecode); -} - -/** - * ipset_parse_icmpv6 - parse an ICMPv6 name or type/code - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an ICMPv6 name or type/code numbers. - * The parsed ICMPv6 type/code is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_icmpv6(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - uint16_t typecode; - - assert(session); - assert(opt == IPSET_OPT_PORT); - assert(str); - - if (name_to_icmpv6(str, &typecode) < 0) - return parse_icmp_typecode(session, opt, str, "ICMPv6"); - - return ipset_session_data_set(session, opt, &typecode); -} - -/** - * ipset_parse_proto_port - parse (optional) protocol and a single port - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as a protocol and port, separated by a colon. - * The protocol part is optional. - * The parsed protocol and port numbers are stored in the data - * blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_proto_port(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - struct ipset_data *data; - char *a, *saved, *tmp; - const char *proto; - uint8_t p = IPPROTO_TCP; - int err = 0; - - assert(session); - assert(opt == IPSET_OPT_PORT); - assert(str); - - data = ipset_session_data(session); - saved = tmp = strdup(str); - if (tmp == NULL) - return ipset_err(session, - "Cannot allocate memory to duplicate %s.", - str); - - a = proto_separator(tmp); - if (a != NULL) { - uint8_t family = ipset_data_family(data); - - /* proto:port */ - *a++ = '\0'; - err = ipset_parse_proto(session, IPSET_OPT_PROTO, tmp); - if (err) - goto error; - - p = *(const uint8_t *) ipset_data_get(data, IPSET_OPT_PROTO); - switch (p) { - case IPPROTO_TCP: - case IPPROTO_SCTP: - case IPPROTO_UDP: - case IPPROTO_UDPLITE: - proto = tmp; - tmp = a; - goto parse_port; - case IPPROTO_ICMP: - if (family != NFPROTO_IPV4) { - syntax_err("Protocol ICMP can be used " - "with family INET only"); - goto error; - } - err = ipset_parse_icmp(session, opt, a); - break; - case IPPROTO_ICMPV6: - if (family != NFPROTO_IPV6) { - syntax_err("Protocol ICMPv6 can be used " - "with family INET6 only"); - goto error; - } - err = ipset_parse_icmpv6(session, opt, a); - break; - default: - if (!STREQ(a, "0")) { - syntax_err("Protocol %s can be used " - "with pseudo port value 0 only."); - goto error; - } - ipset_data_flags_set(data, IPSET_FLAG(opt)); - } - goto error; - } else { - proto = "TCP"; - err = ipset_data_set(data, IPSET_OPT_PROTO, &p); - if (err) - goto error; - } -parse_port: - err = ipset_parse_tcpudp_port(session, opt, tmp, proto); - -error: - free(saved); - return err; -} - -/** - * ipset_parse_family - parse INET|INET6 family names - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an INET|INET6 family name. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_family(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - struct ipset_data *data; - uint8_t family; - - assert(session); - assert(opt == IPSET_OPT_FAMILY); - assert(str); - - data = ipset_session_data(session); - if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_FAMILY))) - syntax_err("protocol family may not be specified " - "multiple times"); - - if (STREQ(str, "inet") || STREQ(str, "ipv4") || STREQ(str, "-4")) - family = NFPROTO_IPV4; - else if (STREQ(str, "inet6") || STREQ(str, "ipv6") || STREQ(str, "-6")) - family = NFPROTO_IPV6; - else if (STREQ(str, "any") || STREQ(str, "unspec")) - family = NFPROTO_UNSPEC; - else - return syntax_err("unknown INET family %s", str); - - return ipset_data_set(data, opt, &family); -} - -/* - * Parse IPv4/IPv6 addresses, networks and ranges. - * We resolve hostnames but just the first IP address is used. - */ - -static struct addrinfo * -call_getaddrinfo(struct ipset_session *session, const char *str, - uint8_t family) -{ - struct addrinfo hints; - struct addrinfo *res; - int err; - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = family; - hints.ai_socktype = SOCK_RAW; - hints.ai_protocol = 0; - hints.ai_next = NULL; - - if ((err = getaddrinfo(str, NULL, &hints, &res)) != 0) { - syntax_err("cannot resolve '%s' to an %s address: %s", - str, family == NFPROTO_IPV6 ? "IPv6" : "IPv4", - gai_strerror(err)); - return NULL; - } else - return res; -} - -static int -get_addrinfo(struct ipset_session *session, - enum ipset_opt opt, - const char *str, - struct addrinfo **info, - uint8_t family) -{ - struct addrinfo *i; - size_t addrlen = family == NFPROTO_IPV4 ? sizeof(struct sockaddr_in) - : sizeof(struct sockaddr_in6); - int found, err = 0; - - if ((*info = call_getaddrinfo(session, str, family)) == NULL) { - syntax_err("cannot parse %s: resolving to %s address failed", - str, family == NFPROTO_IPV4 ? "IPv4" : "IPv6"); - return EINVAL; - } - - for (i = *info, found = 0; i != NULL; i = i->ai_next) { - if (i->ai_family != family || i->ai_addrlen != addrlen) - continue; - if (found == 0) { - if (family == NFPROTO_IPV4) { - /* Workaround: direct cast increases - * required alignment on Sparc - */ - const struct sockaddr_in *saddr = - (void *)i->ai_addr; - err = ipset_session_data_set(session, - opt, &saddr->sin_addr); - } else { - /* Workaround: direct cast increases - * required alignment on Sparc - */ - const struct sockaddr_in6 *saddr = - (void *)i->ai_addr; - err = ipset_session_data_set(session, - opt, &saddr->sin6_addr); - } - } else if (found == 1) { - ipset_warn(session, - "%s resolves to multiple addresses: " - "using only the first one returned " - "by the resolver", - str); - } - found++; - } - if (found == 0) - return syntax_err("cannot parse %s: " - "%s address could not be resolved", - str, family == NFPROTO_IPV4 ? "IPv4" : "IPv6"); - return err; -} - -static int -parse_ipaddr(struct ipset_session *session, - enum ipset_opt opt, const char *str, - uint8_t family) -{ - uint8_t m = family == NFPROTO_IPV4 ? 32 : 128; - int aerr = EINVAL, err = 0, range = 0; - char *saved = strdup(str); - char *a, *tmp = saved; - struct addrinfo *info; - enum ipset_opt copt, opt2; - - if (opt == IPSET_OPT_IP) { - copt = IPSET_OPT_CIDR; - opt2 = IPSET_OPT_IP_TO; - } else { - copt = IPSET_OPT_CIDR2; - opt2 = IPSET_OPT_IP2_TO; - } - - if (tmp == NULL) - return ipset_err(session, - "Cannot allocate memory to duplicate %s.", - str); - if ((a = cidr_separator(tmp)) != NULL) { - /* IP/mask */ - *a++ = '\0'; - - if ((err = string_to_cidr(session, a, 0, m, &m)) != 0 || - (err = ipset_session_data_set(session, copt, &m)) != 0) - goto out; - } else if ((a = range_separator(tmp)) != NULL) { - /* IP-IP */ - *a++ = '\0'; - D("range %s", a); - range++; - } - if ((aerr = get_addrinfo(session, opt, tmp, &info, family)) != 0 || - !range) - goto out; - freeaddrinfo(info); - aerr = get_addrinfo(session, opt2, a, &info, family); - -out: - if (aerr != EINVAL) - /* getaddrinfo not failed */ - freeaddrinfo(info); - else if (aerr) - err = -1; - free(saved); - return err; -} - -enum ipaddr_type { - IPADDR_ANY, - IPADDR_PLAIN, - IPADDR_NET, - IPADDR_RANGE, -}; - -static inline bool -cidr_hostaddr(const char *str, uint8_t family) -{ - char *a = cidr_separator(str); - - return family == NFPROTO_IPV4 ? STREQ(a, "/32") : STREQ(a, "/128"); -} - -static int -parse_ip(struct ipset_session *session, - enum ipset_opt opt, const char *str, enum ipaddr_type addrtype) -{ - struct ipset_data *data = ipset_session_data(session); - uint8_t family = ipset_data_family(data); - - if (family == NFPROTO_UNSPEC) { - family = NFPROTO_IPV4; - ipset_data_set(data, IPSET_OPT_FAMILY, &family); - } - - switch (addrtype) { - case IPADDR_PLAIN: - if (range_separator(str) || - (cidr_separator(str) && !cidr_hostaddr(str, family))) - return syntax_err("plain IP address must be supplied: " - "%s", str); - break; - case IPADDR_NET: - if (!cidr_separator(str) || range_separator(str)) - return syntax_err("IP/netblock must be supplied: %s", - str); - break; - case IPADDR_RANGE: - if (!range_separator(str) || cidr_separator(str)) - return syntax_err("IP-IP range must supplied: %s", - str); - break; - case IPADDR_ANY: - default: - break; - } - - return parse_ipaddr(session, opt, str, family); -} - -/** - * ipset_parse_ip - parse IPv4|IPv6 address, range or netblock - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an IPv4|IPv6 address or address range - * or netblock. Hostnames are resolved. If family is not set - * yet in the data blob, INET is assumed. - * The values are stored in the data blob of the session. - * - * FIXME: if the hostname resolves to multiple addresses, - * the first one is used only. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_ip(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - assert(session); - assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2); - assert(str); - - return parse_ip(session, opt, str, IPADDR_ANY); -} - -/** - * ipset_parse_single_ip - parse a single IPv4|IPv6 address - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an IPv4|IPv6 address or hostname. If family - * is not set yet in the data blob, INET is assumed. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_single_ip(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - assert(session); - assert(opt == IPSET_OPT_IP || - opt == IPSET_OPT_IP_TO || - opt == IPSET_OPT_IP2); - assert(str); - - return parse_ip(session, opt, str, IPADDR_PLAIN); -} - -/** - * ipset_parse_net - parse IPv4|IPv6 address/cidr - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an IPv4|IPv6 address/cidr pattern. If family - * is not set yet in the data blob, INET is assumed. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_net(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - assert(session); - assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2); - assert(str); - - return parse_ip(session, opt, str, IPADDR_NET); -} - -/** - * ipset_parse_range - parse IPv4|IPv6 ranges - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an IPv4|IPv6 range separated by a dash. If family - * is not set yet in the data blob, INET is assumed. - * The values are stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_range(struct ipset_session *session, - enum ipset_opt opt ASSERT_UNUSED, const char *str) -{ - assert(session); - assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2); - assert(str); - - return parse_ip(session, IPSET_OPT_IP, str, IPADDR_RANGE); -} - -/** - * ipset_parse_netrange - parse IPv4|IPv6 address/cidr or range - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an IPv4|IPv6 address/cidr pattern or a range - * of addresses separated by a dash. If family is not set yet in - * the data blob, INET is assumed. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_netrange(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - assert(session); - assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2); - assert(str); - - if (!(range_separator(str) || cidr_separator(str))) - return syntax_err("IP/cidr or IP-IP range must be specified: " - "%s", str); - return parse_ip(session, opt, str, IPADDR_ANY); -} - -/** - * ipset_parse_iprange - parse IPv4|IPv6 address or range - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an IPv4|IPv6 address pattern or a range - * of addresses separated by a dash. If family is not set yet in - * the data blob, INET is assumed. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_iprange(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - assert(session); - assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2); - assert(str); - - if (cidr_separator(str)) - return syntax_err("IP address or IP-IP range must be " - "specified: %s", str); - return parse_ip(session, opt, str, IPADDR_ANY); -} - -/** - * ipset_parse_ipnet - parse IPv4|IPv6 address or address/cidr pattern - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an IPv4|IPv6 address or address/cidr pattern. - * If family is not set yet in the data blob, INET is assumed. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_ipnet(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - assert(session); - assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2); - assert(str); - - if (range_separator(str)) - return syntax_err("IP address or IP/cidr must be specified: %s", - str); - return parse_ip(session, opt, str, IPADDR_ANY); -} - -/** - * ipset_parse_ip4_single6 - parse IPv4 address, range or netblock or IPv6 address - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an IPv4 address or address range - * or netblock or and IPv6 address. Hostnames are resolved. If family - * is not set yet in the data blob, INET is assumed. - * The values are stored in the data blob of the session. - * - * FIXME: if the hostname resolves to multiple addresses, - * the first one is used only. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_ip4_single6(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - struct ipset_data *data; - uint8_t family; - - assert(session); - assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2); - assert(str); - - data = ipset_session_data(session); - family = ipset_data_family(data); - - if (family == NFPROTO_UNSPEC) { - family = NFPROTO_IPV4; - ipset_data_set(data, IPSET_OPT_FAMILY, &family); - } - - return family == NFPROTO_IPV4 ? ipset_parse_ip(session, opt, str) - : ipset_parse_single_ip(session, opt, str); - -} - -/** - * ipset_parse_ip4_net6 - parse IPv4|IPv6 address or address/cidr pattern - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an IPv4|IPv6 address or address/cidr pattern. For IPv4, - * address range is valid too. - * If family is not set yet in the data blob, INET is assumed. - * The values are stored in the data blob of the session. - * - * FIXME: if the hostname resolves to multiple addresses, - * the first one is used only. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_ip4_net6(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - struct ipset_data *data; - uint8_t family; - - assert(session); - assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2); - assert(str); - - data = ipset_session_data(session); - family = ipset_data_family(data); - - if (family == NFPROTO_UNSPEC) { - family = NFPROTO_IPV4; - ipset_data_set(data, IPSET_OPT_FAMILY, &family); - } - - return family == NFPROTO_IPV4 ? parse_ip(session, opt, str, IPADDR_ANY) - : ipset_parse_ipnet(session, opt, str); - -} - -/** - * ipset_parse_iptimeout - parse IPv4|IPv6 address and timeout - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an IPv4|IPv6 address and timeout parameter. - * If family is not set yet in the data blob, INET is assumed. - * The value is stored in the data blob of the session. - * - * Compatibility parser. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_iptimeout(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - char *tmp, *saved, *a; - int err; - - assert(session); - assert(opt == IPSET_OPT_IP); - assert(str); - - /* IP,timeout */ - if (ipset_data_flags_test(ipset_session_data(session), - IPSET_FLAG(IPSET_OPT_TIMEOUT))) - return syntax_err("mixed syntax, timeout already specified"); - - tmp = saved = strdup(str); - if (saved == NULL) - return ipset_err(session, - "Cannot allocate memory to duplicate %s.", - str); - - a = elem_separator(tmp); - if (a == NULL) { - free(saved); - return syntax_err("Missing separator from %s", str); - } - *a++ = '\0'; - err = parse_ip(session, opt, tmp, IPADDR_ANY); - if (!err) - err = ipset_parse_uint32(session, IPSET_OPT_TIMEOUT, a); - - free(saved); - return err; -} - -#define check_setname(str, saved) \ -do { \ - if (strlen(str) > IPSET_MAXNAMELEN - 1) { \ - if (saved != NULL) \ - free(saved); \ - return syntax_err("setname '%s' is longer than %u characters",\ - str, IPSET_MAXNAMELEN - 1); \ - } \ -} while (0) - - -/** - * ipset_parse_name_compat - parse setname as element - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as a setname or a setname element to add to a set. - * The pattern "setname,before|after,setname" is recognized and - * parsed. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_name_compat(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - char *saved; - char *a = NULL, *b = NULL, *tmp; - int err, before = 0; - const char *sep = IPSET_ELEM_SEPARATOR; - struct ipset_data *data; - - assert(session); - assert(opt == IPSET_OPT_NAME); - assert(str); - - data = ipset_session_data(session); - if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_NAMEREF))) - syntax_err("mixed syntax, before|after option already used"); - - tmp = saved = strdup(str); - if (saved == NULL) - return ipset_err(session, - "Cannot allocate memory to duplicate %s.", - str); - if ((a = elem_separator(tmp)) != NULL) { - /* setname,[before|after,setname */ - *a++ = '\0'; - if ((b = elem_separator(a)) != NULL) - *b++ = '\0'; - if (b == NULL || - !(STREQ(a, "before") || STREQ(a, "after"))) { - err = ipset_err(session, "you must specify elements " - "as setname%s[before|after]%ssetname", - sep, sep); - goto out; - } - before = STREQ(a, "before"); - } - check_setname(tmp, saved); - if ((err = ipset_data_set(data, opt, tmp)) != 0 || b == NULL) - goto out; - - check_setname(b, saved); - if ((err = ipset_data_set(data, - IPSET_OPT_NAMEREF, b)) != 0) - goto out; - - if (before) - err = ipset_data_set(data, IPSET_OPT_BEFORE, &before); - -out: - free(saved); - return err; -} - -/** - * ipset_parse_setname - parse string as a setname - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as a setname. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_setname(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - assert(session); - assert(opt == IPSET_SETNAME || - opt == IPSET_OPT_NAME || - opt == IPSET_OPT_SETNAME2); - assert(str); - - check_setname(str, NULL); - - return ipset_session_data_set(session, opt, str); -} - -/** - * ipset_parse_before - parse string as "before" reference setname - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as a "before" reference setname for list:set - * type of sets. The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_before(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - struct ipset_data *data; - - assert(session); - assert(opt == IPSET_OPT_NAMEREF); - assert(str); - - data = ipset_session_data(session); - if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_NAMEREF))) - syntax_err("mixed syntax, before|after option already used"); - - check_setname(str, NULL); - ipset_data_set(data, IPSET_OPT_BEFORE, str); - - return ipset_data_set(data, opt, str); -} - -/** - * ipset_parse_after - parse string as "after" reference setname - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as a "after" reference setname for list:set - * type of sets. The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_after(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - struct ipset_data *data; - - assert(session); - assert(opt == IPSET_OPT_NAMEREF); - assert(str); - - data = ipset_session_data(session); - if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_NAMEREF))) - syntax_err("mixed syntax, before|after option already used"); - - check_setname(str, NULL); - - return ipset_data_set(data, opt, str); -} - -/** - * ipset_parse_uint32 - parse string as an unsigned integer - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an unsigned integer number. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_uint32(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - uint32_t value; - int err; - - assert(session); - assert(str); - - if ((err = string_to_u32(session, str, &value)) == 0) - return ipset_session_data_set(session, opt, &value); - - return err; -} - -/** - * ipset_parse_uint8 - parse string as an unsigned short integer - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an unsigned short integer number. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_uint8(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - uint8_t value; - int err; - - assert(session); - assert(str); - - if ((err = string_to_u8(session, str, &value)) == 0) - return ipset_session_data_set(session, opt, &value); - - return err; -} - -/** - * ipset_parse_netmask - parse string as a CIDR netmask value - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as a CIDR netmask value, depending on family type. - * If family is not set yet, INET is assumed. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_netmask(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - uint8_t family, cidr; - struct ipset_data *data; - int err = 0; - - assert(session); - assert(opt == IPSET_OPT_NETMASK); - assert(str); - - data = ipset_session_data(session); - family = ipset_data_family(data); - if (family == NFPROTO_UNSPEC) { - family = NFPROTO_IPV4; - ipset_data_set(data, IPSET_OPT_FAMILY, &family); - } - - err = string_to_cidr(session, str, - family == NFPROTO_IPV4 ? 1 : 4, - family == NFPROTO_IPV4 ? 31 : 124, - &cidr); - - if (err) - return syntax_err("netmask is out of the inclusive range " - "of %u-%u", - family == NFPROTO_IPV4 ? 1 : 4, - family == NFPROTO_IPV4 ? 31 : 124); - - return ipset_data_set(data, opt, &cidr); -} - -/** - * ipset_parse_flag - "parse" option flags - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse option flags :-) - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_flag(struct ipset_session *session, - enum ipset_opt opt, const char *str UNUSED) -{ - assert(session); - - return ipset_session_data_set(session, opt, NULL); -} - -/** - * ipset_parse_type - parse ipset type name - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse ipset module type: supports both old and new formats. - * The type name is looked up and the type found is stored - * in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_typename(struct ipset_session *session, - enum ipset_opt opt ASSERT_UNUSED, const char *str) -{ - const struct ipset_type *type; - const char *typename; - - assert(session); - assert(opt == IPSET_OPT_TYPENAME); - assert(str); - - if (strlen(str) > IPSET_MAXNAMELEN - 1) - return syntax_err("typename '%s' is longer than %u characters", - str, IPSET_MAXNAMELEN - 1); - - /* Find the corresponding type */ - typename = ipset_typename_resolve(str); - if (typename == NULL) - return syntax_err("typename '%s' is unkown", str); - ipset_session_data_set(session, IPSET_OPT_TYPENAME, typename); - type = ipset_type_get(session, IPSET_CMD_CREATE); - - if (type == NULL) - return -1; - - return ipset_session_data_set(session, IPSET_OPT_TYPE, type); -} - -/** - * ipset_parse_iface - parse string as an interface name - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as an interface name, optionally with 'physdev:' prefix. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_iface(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - struct ipset_data *data; - int offset = 0, err = 0; - - assert(session); - assert(opt == IPSET_OPT_IFACE); - assert(str); - - data = ipset_session_data(session); - if (STREQ(str, "physdev:")) { - offset = 8; - err = ipset_data_set(data, IPSET_OPT_PHYSDEV, str); - } - if (strlen(str + offset) > IFNAMSIZ - 1) - return syntax_err("interface name '%s' is longer " - "than %u characters", - str + offset, IFNAMSIZ - 1); - - return ipset_data_set(data, opt, str + offset); -} - -/** - * ipset_parse_output - parse output format name - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse output format names and set session mode. - * The value is stored in the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_output(struct ipset_session *session, - int opt UNUSED, const char *str) -{ - assert(session); - assert(str); - - if (STREQ(str, "plain")) - return ipset_session_output(session, IPSET_LIST_PLAIN); - else if (STREQ(str, "xml")) - return ipset_session_output(session, IPSET_LIST_XML); - else if (STREQ(str, "save")) - return ipset_session_output(session, IPSET_LIST_SAVE); - - return syntax_err("unkown output mode '%s'", str); -} - -/** - * ipset_parse_ignored - "parse" ignored option - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Ignore deprecated options. A single warning is generated - * for every ignored opton. - * - * Returns 0. - */ -int -ipset_parse_ignored(struct ipset_session *session, - enum ipset_opt opt, const char *str) -{ - assert(session); - assert(str); - - if (!ipset_data_ignored(ipset_session_data(session), opt)) - ipset_warn(session, - "Option %s is ignored. " - "Please upgrade your syntax.", str); - - return 0; -} - -/** - * ipset_call_parser - call a parser function - * @session: session structure - * @parsefn: parser function - * @optstr: option name - * @opt: option kind of the data - * @str: string to parse - * - * Wrapper to call the parser functions so that ignored options - * are handled properly. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_call_parser(struct ipset_session *session, - const struct ipset_arg *arg, - const char *str) -{ - if (ipset_data_flags_test(ipset_session_data(session), - IPSET_FLAG(arg->opt))) - syntax_err("%s already specified", arg->name[0]); - - return arg->parse(session, arg->opt, str); -} - -#define parse_elem(s, t, d, str) \ -do { \ - if (!(t)->elem[d - 1].parse) \ - goto internal; \ - ret = (t)->elem[d - 1].parse(s, (t)->elem[d - 1].opt, str); \ - if (ret) \ - goto out; \ -} while (0) - -#define elem_syntax_err(fmt, args...) \ -do { \ - free(saved); \ - return syntax_err(fmt , ## args);\ -} while (0) - -/** - * ipset_parse_elem - parse ADT elem, depending on settype - * @session: session structure - * @opt: option kind of the data - * @str: string to parse - * - * Parse string as a (multipart) element according to the settype. - * The value is stored in the data blob of the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_parse_elem(struct ipset_session *session, - enum ipset_opt optional, const char *str) -{ - const struct ipset_type *type; - char *a = NULL, *b = NULL, *tmp, *saved; - int ret; - - assert(session); - assert(str); - - type = ipset_session_data_get(session, IPSET_OPT_TYPE); - if (!type) - return ipset_err(session, - "Internal error: set type is unknown!"); - - saved = tmp = strdup(str); - if (tmp == NULL) - return ipset_err(session, - "Cannot allocate memory to duplicate %s.", - str); - - a = elem_separator(tmp); - if (type->dimension > IPSET_DIM_ONE) { - if (a != NULL) { - /* elem,elem */ - *a++ = '\0'; - } else if (!optional) - elem_syntax_err("Second element is missing from %s.", - str); - } else if (a != NULL) { - if (type->compat_parse_elem) { - ret = type->compat_parse_elem(session, - type->elem[IPSET_DIM_ONE - 1].opt, - saved); - goto out; - } - elem_syntax_err("Elem separator in %s, " - "but settype %s supports none.", - str, type->name); - } - - if (a) - b = elem_separator(a); - if (type->dimension > IPSET_DIM_TWO) { - if (b != NULL) { - /* elem,elem,elem */ - *b++ = '\0'; - } else if (!optional) - elem_syntax_err("Third element is missing from %s.", - str); - } else if (b != NULL) - elem_syntax_err("Two elem separators in %s, " - "but settype %s supports one.", - str, type->name); - if (b != NULL && elem_separator(b)) - elem_syntax_err("Three elem separators in %s, " - "but settype %s supports two.", - str, type->name); - - D("parse elem part one: %s", tmp); - parse_elem(session, type, IPSET_DIM_ONE, tmp); - - if (type->dimension > IPSET_DIM_ONE && a != NULL) { - D("parse elem part two: %s", a); - parse_elem(session, type, IPSET_DIM_TWO, a); - } - if (type->dimension > IPSET_DIM_TWO && b != NULL) - parse_elem(session, type, IPSET_DIM_THREE, b); - - goto out; - -internal: - ret = ipset_err(session, - "Internal error: missing parser function for %s", - type->name); -out: - free(saved); - return ret; -} diff --git a/extensions/ipset-6/libipset/print.c b/extensions/ipset-6/libipset/print.c deleted file mode 100644 index f04377f..0000000 --- a/extensions/ipset-6/libipset/print.c +++ /dev/null @@ -1,820 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* assert */ -#include /* errno */ -#include /* snprintf */ -#include /* getservbyport */ -#include /* inet_ntop */ -#include /* inet_ntop */ -#include /* inet_ntop */ -#include /* ETH_ALEN */ -#include /* IFNAMSIZ */ - -#include /* D() */ -#include /* ipset_data_* */ -#include /* icmp_to_name */ -#include /* icmpv6_to_name */ -#include /* IPSET_*_SEPARATOR */ -#include /* ipset set types */ -#include /* IPSET_FLAG_ */ -#include /* UNUSED */ -#include /* IPSET_ENV_* */ -#include /* prototypes */ - -/* Print data (to output buffer). All function must follow snprintf. */ - -#define SNPRINTF_FAILURE(size, len, offset) \ -do { \ - if (size < 0 || (unsigned int) size >= len) \ - return size; \ - offset += size; \ - len -= size; \ -} while (0) - -/** - * ipset_print_ether - print ethernet address to string - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print Ethernet address to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_ether(char *buf, unsigned int len, - const struct ipset_data *data, enum ipset_opt opt, - uint8_t env UNUSED) -{ - const unsigned char *ether; - int i, size, offset = 0; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_ETHER); - - if (len < ETH_ALEN*3) - return -1; - - ether = ipset_data_get(data, opt); - assert(ether); - - size = snprintf(buf, len, "%02X", ether[0]); - SNPRINTF_FAILURE(size, len, offset); - for (i = 1; i < ETH_ALEN; i++) { - size = snprintf(buf + offset, len, ":%02X", ether[i]); - SNPRINTF_FAILURE(size, len, offset); - } - - return offset; -} - -/** - * ipset_print_family - print INET family - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print INET family string to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_family(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt ASSERT_UNUSED, - uint8_t env UNUSED) -{ - uint8_t family; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_FAMILY); - - if (len < strlen("inet6") + 1) - return -1; - - family = ipset_data_family(data); - - return snprintf(buf, len, "%s", - family == AF_INET ? "inet" : - family == AF_INET6 ? "inet6" : "any"); -} - -/** - * ipset_print_type - print ipset type string - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print ipset module string identifier to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_type(char *buf, unsigned int len, - const struct ipset_data *data, enum ipset_opt opt, - uint8_t env UNUSED) -{ - const struct ipset_type *type; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_TYPE); - - type = ipset_data_get(data, opt); - assert(type); - if (len < strlen(type->name) + 1) - return -1; - - return snprintf(buf, len, "%s", type->name); -} - -static inline int -__getnameinfo4(char *buf, unsigned int len, - int flags, const union nf_inet_addr *addr) -{ - struct sockaddr_in saddr; - int err; - - memset(&saddr, 0, sizeof(saddr)); - in4cpy(&saddr.sin_addr, &addr->in); - saddr.sin_family = NFPROTO_IPV4; - - err = getnameinfo((const struct sockaddr *)&saddr, - sizeof(saddr), - buf, len, NULL, 0, flags); - - if (!(flags & NI_NUMERICHOST) && - (err == EAI_AGAIN || (err == 0 && strchr(buf, '-') != NULL))) - err = getnameinfo((const struct sockaddr *)&saddr, - sizeof(saddr), - buf, len, NULL, 0, - flags | NI_NUMERICHOST); - D("getnameinfo err: %i, errno %i", err, errno); - return (err == 0 ? (int)strlen(buf) : - (err == EAI_OVERFLOW || err == EAI_SYSTEM) ? (int)len : -1); -} - -static inline int -__getnameinfo6(char *buf, unsigned int len, - int flags, const union nf_inet_addr *addr) -{ - struct sockaddr_in6 saddr; - int err; - - memset(&saddr, 0, sizeof(saddr)); - in6cpy(&saddr.sin6_addr, &addr->in6); - saddr.sin6_family = NFPROTO_IPV6; - - err = getnameinfo((const struct sockaddr *)&saddr, - sizeof(saddr), - buf, len, NULL, 0, flags); - - if (!(flags & NI_NUMERICHOST) && - (err == EAI_AGAIN || (err == 0 && strchr(buf, '-') != NULL))) - err = getnameinfo((const struct sockaddr *)&saddr, - sizeof(saddr), - buf, len, NULL, 0, - flags | NI_NUMERICHOST); - D("getnameinfo err: %i, errno %i", err, errno); - return (err == 0 ? (int)strlen(buf) : - (err == EAI_OVERFLOW || err == EAI_SYSTEM) ? (int)len : -1); -} - -#define SNPRINTF_IP(mask, f) \ -static int \ -snprintf_ipv##f(char *buf, unsigned int len, int flags, \ - const union nf_inet_addr *ip, uint8_t cidr) \ -{ \ - int size, offset = 0; \ - \ - size = __getnameinfo##f(buf, len, flags, ip); \ - SNPRINTF_FAILURE(size, len, offset); \ - \ - D("cidr %u mask %u", cidr, mask); \ - if (cidr == mask) \ - return offset; \ - D("print cidr"); \ - size = snprintf(buf + offset, len, \ - "%s%u", IPSET_CIDR_SEPARATOR, cidr); \ - SNPRINTF_FAILURE(size, len, offset); \ - return offset; \ -} - -SNPRINTF_IP(32, 4) - -SNPRINTF_IP(128, 6) - -/** - * ipset_print_ip - print IPv4|IPv6 address to string - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print IPv4|IPv6 address, address/cidr or address range to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_ip(char *buf, unsigned int len, - const struct ipset_data *data, enum ipset_opt opt, - uint8_t env) -{ - const union nf_inet_addr *ip; - uint8_t family, cidr; - int flags, size, offset = 0; - enum ipset_opt cidropt; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2); - - D("len: %u", len); - family = ipset_data_family(data); - cidropt = opt == IPSET_OPT_IP ? IPSET_OPT_CIDR : IPSET_OPT_CIDR2; - if (ipset_data_test(data, cidropt)) { - cidr = *(const uint8_t *) ipset_data_get(data, cidropt); - D("CIDR: %u", cidr); - } else - cidr = family == NFPROTO_IPV6 ? 128 : 32; - flags = (env & IPSET_ENV_RESOLVE) ? 0 : NI_NUMERICHOST; - - ip = ipset_data_get(data, opt); - assert(ip); - if (family == NFPROTO_IPV4) - size = snprintf_ipv4(buf, len, flags, ip, cidr); - else if (family == NFPROTO_IPV6) - size = snprintf_ipv6(buf, len, flags, ip, cidr); - else - return -1; - D("size %i, len %u", size, len); - SNPRINTF_FAILURE(size, len, offset); - - D("len: %u, offset %u", len, offset); - if (!ipset_data_test(data, IPSET_OPT_IP_TO)) - return offset; - - size = snprintf(buf + offset, len, "%s", IPSET_RANGE_SEPARATOR); - SNPRINTF_FAILURE(size, len, offset); - - ip = ipset_data_get(data, IPSET_OPT_IP_TO); - if (family == NFPROTO_IPV4) - size = snprintf_ipv4(buf + offset, len, flags, ip, cidr); - else if (family == NFPROTO_IPV6) - size = snprintf_ipv6(buf + offset, len, flags, ip, cidr); - else - return -1; - - SNPRINTF_FAILURE(size, len, offset); - return offset; -} - -/** - * ipset_print_ipaddr - print IPv4|IPv6 address to string - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print IPv4|IPv6 address or address/cidr to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_ipaddr(char *buf, unsigned int len, - const struct ipset_data *data, enum ipset_opt opt, - uint8_t env) -{ - const union nf_inet_addr *ip; - uint8_t family, cidr; - enum ipset_opt cidropt; - int flags; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_IP || - opt == IPSET_OPT_IP_TO || - opt == IPSET_OPT_IP2); - - family = ipset_data_family(data); - cidropt = opt == IPSET_OPT_IP ? IPSET_OPT_CIDR : IPSET_OPT_CIDR2; - if (ipset_data_test(data, cidropt)) - cidr = *(const uint8_t *) ipset_data_get(data, cidropt); - else - cidr = family == NFPROTO_IPV6 ? 128 : 32; - flags = (env & IPSET_ENV_RESOLVE) ? 0 : NI_NUMERICHOST; - - ip = ipset_data_get(data, opt); - assert(ip); - if (family == NFPROTO_IPV4) - return snprintf_ipv4(buf, len, flags, ip, cidr); - else if (family == NFPROTO_IPV6) - return snprintf_ipv6(buf, len, flags, ip, cidr); - - return -1; -} - -/** - * ipset_print_number - print number to string - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print number to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_number(char *buf, unsigned int len, - const struct ipset_data *data, enum ipset_opt opt, - uint8_t env UNUSED) -{ - size_t maxsize; - const void *number; - - assert(buf); - assert(len > 0); - assert(data); - - number = ipset_data_get(data, opt); - maxsize = ipset_data_sizeof(opt, AF_INET); - D("opt: %u, maxsize %zu", opt, maxsize); - if (maxsize == sizeof(uint8_t)) - return snprintf(buf, len, "%u", *(const uint8_t *) number); - else if (maxsize == sizeof(uint16_t)) - return snprintf(buf, len, "%u", *(const uint16_t *) number); - else if (maxsize == sizeof(uint32_t)) - return snprintf(buf, len, "%lu", - (long unsigned) *(const uint32_t *) number); - else - assert(0); - return 0; -} - -/** - * ipset_print_name - print setname element string - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print setname element string to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_name(char *buf, unsigned int len, - const struct ipset_data *data, enum ipset_opt opt, - uint8_t env UNUSED) -{ - const char *name; - int size, offset = 0; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_NAME); - - if (len < 2*IPSET_MAXNAMELEN + 2 + strlen("before")) - return -1; - - name = ipset_data_get(data, opt); - assert(name); - size = snprintf(buf, len, "%s", name); - SNPRINTF_FAILURE(size, len, offset); - - if (ipset_data_test(data, IPSET_OPT_NAMEREF)) { - bool before = false; - if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_FLAGS))) { - const uint32_t *flags = - ipset_data_get(data, IPSET_OPT_FLAGS); - before = (*flags) & IPSET_FLAG_BEFORE; - } - size = snprintf(buf + offset, len, - " %s %s", before ? "before" : "after", - (const char *) ipset_data_get(data, - IPSET_OPT_NAMEREF)); - SNPRINTF_FAILURE(size, len, offset); - } - - return offset; -} - -/** - * ipset_print_port - print port or port range - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print port or port range to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_port(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt ASSERT_UNUSED, - uint8_t env UNUSED) -{ - const uint16_t *port; - int size, offset = 0; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_PORT); - - if (len < 2*strlen("65535") + 2) - return -1; - - port = ipset_data_get(data, IPSET_OPT_PORT); - assert(port); - size = snprintf(buf, len, "%u", *port); - SNPRINTF_FAILURE(size, len, offset); - - if (ipset_data_test(data, IPSET_OPT_PORT_TO)) { - port = ipset_data_get(data, IPSET_OPT_PORT_TO); - size = snprintf(buf + offset, len, - "%s%u", - IPSET_RANGE_SEPARATOR, *port); - SNPRINTF_FAILURE(size, len, offset); - } - - return offset; -} - -/** - * ipset_print_iface - print interface element string - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print interface element string to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_iface(char *buf, unsigned int len, - const struct ipset_data *data, enum ipset_opt opt, - uint8_t env UNUSED) -{ - const char *name; - int size, offset = 0; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_IFACE); - - if (len < IFNAMSIZ + strlen("physdev:")) - return -1; - - if (ipset_data_test(data, IPSET_OPT_PHYSDEV)) { - size = snprintf(buf, len, "physdev:"); - SNPRINTF_FAILURE(size, len, offset); - } - name = ipset_data_get(data, opt); - assert(name); - size = snprintf(buf, len, "%s", name); - SNPRINTF_FAILURE(size, len, offset); - return offset; -} - -/** - * ipset_print_proto - print protocol name - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print protocol name to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_proto(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt ASSERT_UNUSED, - uint8_t env UNUSED) -{ - const struct protoent *protoent; - uint8_t proto; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_PROTO); - - proto = *(const uint8_t *) ipset_data_get(data, IPSET_OPT_PROTO); - assert(proto); - - protoent = getprotobynumber(proto); - if (protoent) - return snprintf(buf, len, "%s", protoent->p_name); - - /* Should not happen */ - return snprintf(buf, len, "%u", proto); -} - -/** - * ipset_print_icmp - print ICMP code name or type/code - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print ICMP code name or type/code name to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_icmp(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt ASSERT_UNUSED, - uint8_t env UNUSED) -{ - const char *name; - uint16_t typecode; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_PORT); - - typecode = *(const uint16_t *) ipset_data_get(data, IPSET_OPT_PORT); - name = icmp_to_name(typecode >> 8, typecode & 0xFF); - if (name != NULL) - return snprintf(buf, len, "%s", name); - else - return snprintf(buf, len, "%u/%u", - typecode >> 8, typecode & 0xFF); -} - -/** - * ipset_print_icmpv6 - print ICMPv6 code name or type/code - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print ICMPv6 code name or type/code name to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_icmpv6(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt ASSERT_UNUSED, - uint8_t env UNUSED) -{ - const char *name; - uint16_t typecode; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_PORT); - - typecode = *(const uint16_t *) ipset_data_get(data, IPSET_OPT_PORT); - name = icmpv6_to_name(typecode >> 8, typecode & 0xFF); - if (name != NULL) - return snprintf(buf, len, "%s", name); - else - return snprintf(buf, len, "%u/%u", - typecode >> 8, typecode & 0xFF); -} - -/** - * ipset_print_proto_port - print proto:port - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print protocol and port to output buffer. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_proto_port(char *buf, unsigned int len, - const struct ipset_data *data, - enum ipset_opt opt ASSERT_UNUSED, - uint8_t env UNUSED) -{ - int size, offset = 0; - - assert(buf); - assert(len > 0); - assert(data); - assert(opt == IPSET_OPT_PORT); - - if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_PROTO))) { - uint8_t proto = *(const uint8_t *) ipset_data_get(data, - IPSET_OPT_PROTO); - size = ipset_print_proto(buf, len, data, IPSET_OPT_PROTO, env); - SNPRINTF_FAILURE(size, len, offset); - if (len < 2) - return -ENOSPC; - size = snprintf(buf + offset, len, IPSET_PROTO_SEPARATOR); - SNPRINTF_FAILURE(size, len, offset); - - switch (proto) { - case IPPROTO_TCP: - case IPPROTO_SCTP: - case IPPROTO_UDP: - case IPPROTO_UDPLITE: - break; - case IPPROTO_ICMP: - return ipset_print_icmp(buf + offset, len, data, - IPSET_OPT_PORT, env); - case IPPROTO_ICMPV6: - return ipset_print_icmpv6(buf + offset, len, data, - IPSET_OPT_PORT, env); - default: - break; - } - } - size = ipset_print_port(buf + offset, len, data, IPSET_OPT_PORT, env); - SNPRINTF_FAILURE(size, len, offset); - - return offset; -} - -#define print_second(data) \ -ipset_data_flags_test(data, \ - IPSET_FLAG(IPSET_OPT_PORT)|IPSET_FLAG(IPSET_OPT_ETHER)) - -#define print_third(data) \ -ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_IP2)) - -/** - * ipset_print_elem - print ADT elem according to settype - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print (multipart) element according to settype - * - * Return lenght of printed string or error size. - */ -int -ipset_print_elem(char *buf, unsigned int len, - const struct ipset_data *data, enum ipset_opt opt UNUSED, - uint8_t env) -{ - const struct ipset_type *type; - int size, offset = 0; - - assert(buf); - assert(len > 0); - assert(data); - - type = ipset_data_get(data, IPSET_OPT_TYPE); - if (!type) - return -1; - - size = type->elem[IPSET_DIM_ONE - 1].print(buf, len, data, - type->elem[IPSET_DIM_ONE - 1].opt, env); - SNPRINTF_FAILURE(size, len, offset); - IF_D(ipset_data_test(data, type->elem[IPSET_DIM_TWO - 1].opt), - "print second elem"); - if (type->dimension == IPSET_DIM_ONE || - (type->last_elem_optional && - !ipset_data_test(data, type->elem[IPSET_DIM_TWO - 1].opt))) - return offset; - - size = snprintf(buf + offset, len, IPSET_ELEM_SEPARATOR); - SNPRINTF_FAILURE(size, len, offset); - size = type->elem[IPSET_DIM_TWO - 1].print(buf + offset, len, data, - type->elem[IPSET_DIM_TWO - 1].opt, env); - SNPRINTF_FAILURE(size, len, offset); - if (type->dimension == IPSET_DIM_TWO || - (type->last_elem_optional && - !ipset_data_test(data, type->elem[IPSET_DIM_THREE - 1].opt))) - return offset; - - size = snprintf(buf + offset, len, IPSET_ELEM_SEPARATOR); - SNPRINTF_FAILURE(size, len, offset); - size = type->elem[IPSET_DIM_THREE - 1].print(buf + offset, len, data, - type->elem[IPSET_DIM_THREE - 1].opt, env); - SNPRINTF_FAILURE(size, len, offset); - - return offset; -} - -/** - * ipset_print_flag - print a flag - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Print a flag, i.e. option without value - * - * Return lenght of printed string or error size. - */ -int -ipset_print_flag(char *buf UNUSED, unsigned int len UNUSED, - const struct ipset_data *data UNUSED, - enum ipset_opt opt UNUSED, uint8_t env UNUSED) -{ - return 0; -} - -/** - * ipset_print_data - print data, generic fuction - * @buf: printing buffer - * @len: length of available buffer space - * @data: data blob - * @opt: the option kind - * @env: environment flags - * - * Generic wrapper of the printing functions. - * - * Return lenght of printed string or error size. - */ -int -ipset_print_data(char *buf, unsigned int len, - const struct ipset_data *data, enum ipset_opt opt, - uint8_t env) -{ - int size = 0, offset = 0; - - assert(buf); - assert(len > 0); - assert(data); - - switch (opt) { - case IPSET_OPT_FAMILY: - size = ipset_print_family(buf, len, data, opt, env); - break; - case IPSET_OPT_TYPE: - size = ipset_print_type(buf, len, data, opt, env); - break; - case IPSET_SETNAME: - size = snprintf(buf, len, "%s", ipset_data_setname(data)); - break; - case IPSET_OPT_ELEM: - size = ipset_print_elem(buf, len, data, opt, env); - break; - case IPSET_OPT_IP: - size = ipset_print_ip(buf, len, data, opt, env); - break; - case IPSET_OPT_PORT: - size = ipset_print_port(buf, len, data, opt, env); - break; - case IPSET_OPT_IFACE: - size = ipset_print_iface(buf, len, data, opt, env); - break; - case IPSET_OPT_GC: - case IPSET_OPT_HASHSIZE: - case IPSET_OPT_MAXELEM: - case IPSET_OPT_NETMASK: - case IPSET_OPT_PROBES: - case IPSET_OPT_RESIZE: - case IPSET_OPT_TIMEOUT: - case IPSET_OPT_REFERENCES: - case IPSET_OPT_ELEMENTS: - case IPSET_OPT_SIZE: - size = ipset_print_number(buf, len, data, opt, env); - break; - default: - return -1; - } - SNPRINTF_FAILURE(size, len, offset); - - return offset; -} diff --git a/extensions/ipset-6/libipset/session.c b/extensions/ipset-6/libipset/session.c deleted file mode 100644 index 4424020..0000000 --- a/extensions/ipset-6/libipset/session.c +++ /dev/null @@ -1,2013 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* assert */ -#include /* errno */ -#include /* setjmp, longjmp */ -#include /* snprintf */ -#include /* va_* */ -#include /* free */ -#include /* str* */ -#include /* getpagesize */ -#include /* ETH_ALEN */ -#include /* IFNAMSIZ */ - -#include /* D() */ -#include /* IPSET_OPT_* */ -#include /* ipset_errcode */ -#include /* ipset_print_* */ -#include /* struct ipset_type */ -#include /* transport */ -#include /* default backend */ -#include /* STREQ */ -#include /* IPSET_ENV_* */ -#include /* prototypes */ - -#include - -#define IPSET_NEST_MAX 4 - -/* The session structure */ -struct ipset_session { - const struct ipset_transport *transport;/* Transport protocol */ - struct ipset_handle *handle; /* Transport handler */ - struct ipset_data *data; /* Input/output data */ - /* Command state */ - enum ipset_cmd cmd; /* Current command */ - uint32_t lineno; /* Current lineno in restore mode */ - uint32_t printed_set; /* Printed sets so far */ - char saved_setname[IPSET_MAXNAMELEN]; /* Saved setname */ - const struct ipset_type *saved_type; /* Saved type */ - struct nlattr *nested[IPSET_NEST_MAX]; /* Pointer to nest levels */ - uint8_t nestid; /* Current nest level */ - bool version_checked; /* Version checked */ - /* Output buffer */ - char outbuf[IPSET_OUTBUFLEN]; /* Output buffer */ - enum ipset_output_mode mode; /* Output mode */ - ipset_outfn outfn; /* Output function */ - /* Error/warning reporting */ - char report[IPSET_ERRORBUFLEN]; /* Error/report buffer */ - char *errmsg; - char *warnmsg; - uint8_t envopts; /* Session env opts */ - /* Kernel message buffer */ - size_t bufsize; - void *buffer; -}; - -/* - * Glue functions - */ - -/** - * ipset_session_data - return pointer to the data - * @session: session structure - * - * Returns the pointer to the data structure of the session. - */ -struct ipset_data * -ipset_session_data(const struct ipset_session *session) -{ - assert(session); - return session->data; -} - -/** - * ipset_session_handle - return pointer to the handle - * @session: session structure - * - * Returns the pointer to the transport handle structure of the session. - */ -struct ipset_handle * -ipset_session_handle(const struct ipset_session *session) -{ - assert(session); - return session->handle; -} - -/** - * ipset_saved_type - return pointer to the saved type - * @session: session structure - * - * Returns the pointer to the saved type from the last ipset_cmd - * It is required to decode type-specific error codes in restore mode. - */ -const struct ipset_type * -ipset_saved_type(const struct ipset_session *session) -{ - assert(session); - return session->saved_type; -} - -/** - * ipset_session_lineno - set session lineno - * @session: session structure - * - * Set session lineno to report parser errors correctly. - */ -void -ipset_session_lineno(struct ipset_session *session, uint32_t lineno) -{ - assert(session); - session->lineno = lineno; -} - -/* - * Environment options - */ - -/** - * ipset_envopt_parse - parse/set environment option - * @session: session structure - * @opt: environment option - * @arg: option argument (unused) - * - * Parse and set an environment option. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_envopt_parse(struct ipset_session *session, int opt, - const char *arg UNUSED) -{ - assert(session); - - switch (opt) { - case IPSET_ENV_SORTED: - case IPSET_ENV_QUIET: - case IPSET_ENV_RESOLVE: - case IPSET_ENV_EXIST: - case IPSET_ENV_LIST_SETNAME: - case IPSET_ENV_LIST_HEADER: - session->envopts |= opt; - return 0; - default: - break; - } - return -1; -} - -/** - * ipset_envopt_test - test environment option - * @session: session structure - * @opt: environment option - * - * Test whether the environment option is set in the session. - * - * Returns true or false. - */ -bool -ipset_envopt_test(struct ipset_session *session, enum ipset_envopt opt) -{ - assert(session); - return session->envopts & opt; -} - -/** - * ipset_session_output - set the session output mode - * @session: session structure - * @mode: output mode - * - * Set the output mode for the session. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_session_output(struct ipset_session *session, - enum ipset_output_mode mode) -{ - assert(session); - session->mode = mode; - return 0; -} - -/* - * Error and warning reporting - */ - -/** - * ipset_session_report - fill the report buffer - * @session: session structure - * @type: report type - * @fmt: message format - * - * Fill the report buffer with an error or warning message. - * Depending on the report type, set the error or warning - * message pointer. - * - * Returns -1. - */ -int __attribute__((format(printf, 3, 4))) -ipset_session_report(struct ipset_session *session, - enum ipset_err_type type, - const char *fmt, ...) -{ - int len, offset = 0; - va_list args; - - assert(session); - assert(fmt); - - if (session->lineno != 0 && type == IPSET_ERROR) { - sprintf(session->report, "Error in line %u: ", - session->lineno); - } - offset = strlen(session->report); - - va_start(args, fmt); - len = vsnprintf(session->report + offset, - IPSET_ERRORBUFLEN - 1 - offset, - fmt, args); - va_end(args); - - if (len >= IPSET_ERRORBUFLEN - 1 - offset) - session->report[IPSET_ERRORBUFLEN - 1] = '\0'; - if (strlen(session->report) < IPSET_ERRORBUFLEN - 1) - strcat(session->report, "\n"); - - if (type == IPSET_ERROR) { - session->errmsg = session->report; - session->warnmsg = NULL; - } else { - session->errmsg = NULL; - session->warnmsg = session->report; - } - return -1; -} - -/** - * ipset_session_reset - reset the report buffer - * @session: session structure - * - * Reset the report buffer, the error and warning pointers. - */ -void -ipset_session_report_reset(struct ipset_session *session) -{ - assert(session); - session->report[0] = '\0'; - session->errmsg = session->warnmsg = NULL; -} - -/** - * ipset_session_error - return the report buffer as error - * @session: session structure - * - * Return the pointer to the report buffer as an error report. - * If there is no error message in the buffer, NULL returned. - */ -const char * -ipset_session_error(const struct ipset_session *session) -{ - assert(session); - - return session->errmsg; -} - -/** - * ipset_session_warning - return the report buffer as warning - * @session: session structure - * - * Return the pointer to the report buffer as a warning report. - * If there is no warning message in the buffer, NULL returned. - */ -const char * -ipset_session_warning(const struct ipset_session *session) -{ - assert(session); - - return session->warnmsg; -} - -/* - * Receive data from the kernel - */ - -struct ipset_attr_policy { - uint16_t type; - uint16_t len; - enum ipset_opt opt; -}; - -/* Attribute policies and mapping to options */ -static const struct ipset_attr_policy cmd_attrs[] = { - [IPSET_ATTR_PROTOCOL] = { - .type = MNL_TYPE_U8, - }, - [IPSET_ATTR_SETNAME] = { - .type = MNL_TYPE_NUL_STRING, - .opt = IPSET_SETNAME, - .len = IPSET_MAXNAMELEN, - }, - [IPSET_ATTR_TYPENAME] = { - .type = MNL_TYPE_NUL_STRING, - .opt = IPSET_OPT_TYPENAME, - .len = IPSET_MAXNAMELEN, - }, - /* IPSET_ATTR_SETNAME2 is an alias for IPSET_ATTR_TYPENAME */ - [IPSET_ATTR_REVISION] = { - .type = MNL_TYPE_U8, - .opt = IPSET_OPT_REVISION, - }, - [IPSET_ATTR_FAMILY] = { - .type = MNL_TYPE_U8, - .opt = IPSET_OPT_FAMILY, - }, - [IPSET_ATTR_FLAGS] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_FLAGS, - }, - [IPSET_ATTR_DATA] = { - .type = MNL_TYPE_NESTED, - }, - [IPSET_ATTR_ADT] = { - .type = MNL_TYPE_NESTED, - }, - [IPSET_ATTR_REVISION_MIN] = { - .type = MNL_TYPE_U8, - .opt = IPSET_OPT_REVISION_MIN, - }, - /* IPSET_ATTR_PROTOCOL_MIN is an alias for IPSET_ATTR_REVISION_MIN */ - [IPSET_ATTR_LINENO] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_LINENO, - }, -}; - -static const struct ipset_attr_policy create_attrs[] = { - [IPSET_ATTR_IP] = { - .type = MNL_TYPE_NESTED, - .opt = IPSET_OPT_IP, - }, - [IPSET_ATTR_IP_TO] = { - .type = MNL_TYPE_NESTED, - .opt = IPSET_OPT_IP_TO, - }, - [IPSET_ATTR_CIDR] = { - .type = MNL_TYPE_U8, - .opt = IPSET_OPT_CIDR, - }, - [IPSET_ATTR_PORT] = { - .type = MNL_TYPE_U16, - .opt = IPSET_OPT_PORT, - }, - [IPSET_ATTR_PORT_TO] = { - .type = MNL_TYPE_U16, - .opt = IPSET_OPT_PORT_TO, - }, - [IPSET_ATTR_TIMEOUT] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_TIMEOUT, - }, - [IPSET_ATTR_PROTO] = { - .type = MNL_TYPE_U8, - .opt = IPSET_OPT_PROTO, - }, - [IPSET_ATTR_CADT_FLAGS] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_CADT_FLAGS, - }, - [IPSET_ATTR_GC] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_GC, - }, - [IPSET_ATTR_HASHSIZE] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_HASHSIZE, - }, - [IPSET_ATTR_MAXELEM] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_MAXELEM, - }, - [IPSET_ATTR_NETMASK] = { - .type = MNL_TYPE_U8, - .opt = IPSET_OPT_NETMASK, - }, - [IPSET_ATTR_PROBES] = { - .type = MNL_TYPE_U8, - .opt = IPSET_OPT_PROBES, - }, - [IPSET_ATTR_RESIZE] = { - .type = MNL_TYPE_U8, - .opt = IPSET_OPT_RESIZE, - }, - [IPSET_ATTR_SIZE] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_SIZE, - }, - [IPSET_ATTR_ELEMENTS] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_ELEMENTS, - }, - [IPSET_ATTR_REFERENCES] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_REFERENCES, - }, - [IPSET_ATTR_MEMSIZE] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_MEMSIZE, - }, -}; - -static const struct ipset_attr_policy adt_attrs[] = { - [IPSET_ATTR_IP] = { - .type = MNL_TYPE_NESTED, - .opt = IPSET_OPT_IP, - }, - [IPSET_ATTR_IP_TO] = { - .type = MNL_TYPE_NESTED, - .opt = IPSET_OPT_IP_TO, - }, - [IPSET_ATTR_CIDR] = { - .type = MNL_TYPE_U8, - .opt = IPSET_OPT_CIDR, - }, - [IPSET_ATTR_PORT] = { - .type = MNL_TYPE_U16, - .opt = IPSET_OPT_PORT, - }, - [IPSET_ATTR_PORT_TO] = { - .type = MNL_TYPE_U16, - .opt = IPSET_OPT_PORT_TO, - }, - [IPSET_ATTR_PROTO] = { - .type = MNL_TYPE_U8, - .opt = IPSET_OPT_PROTO, - }, - [IPSET_ATTR_TIMEOUT] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_TIMEOUT, - }, - [IPSET_ATTR_CADT_FLAGS] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_CADT_FLAGS, - }, - [IPSET_ATTR_LINENO] = { - .type = MNL_TYPE_U32, - .opt = IPSET_OPT_LINENO, - }, - [IPSET_ATTR_ETHER] = { - .type = MNL_TYPE_BINARY, - .opt = IPSET_OPT_ETHER, - .len = ETH_ALEN, - }, - [IPSET_ATTR_NAME] = { - .type = MNL_TYPE_NUL_STRING, - .opt = IPSET_OPT_NAME, - .len = IPSET_MAXNAMELEN, - }, - [IPSET_ATTR_NAMEREF] = { - .type = MNL_TYPE_NUL_STRING, - .opt = IPSET_OPT_NAMEREF, - .len = IPSET_MAXNAMELEN, - }, - [IPSET_ATTR_IP2] = { - .type = MNL_TYPE_NESTED, - .opt = IPSET_OPT_IP2, - }, - [IPSET_ATTR_CIDR2] = { - .type = MNL_TYPE_U8, - .opt = IPSET_OPT_CIDR2, - }, - [IPSET_ATTR_IP2_TO] = { - .type = MNL_TYPE_NESTED, - .opt = IPSET_OPT_IP2_TO, - }, - [IPSET_ATTR_IFACE] = { - .type = MNL_TYPE_NUL_STRING, - .opt = IPSET_OPT_IFACE, - .len = IFNAMSIZ, - }, -}; - -static const struct ipset_attr_policy ipaddr_attrs[] = { - [IPSET_ATTR_IPADDR_IPV4] = { - .type = MNL_TYPE_U32, - }, - [IPSET_ATTR_IPADDR_IPV6] = { - .type = MNL_TYPE_BINARY, - .len = sizeof(union nf_inet_addr), - }, -}; - -#ifdef IPSET_DEBUG -static int debug = 1; -#endif - -static int -generic_data_attr_cb(const struct nlattr *attr, void *data, - int attr_max, const struct ipset_attr_policy *policy) -{ - const struct nlattr **tb = data; - int type = mnl_attr_get_type(attr); - - IF_D(debug, "attr type: %u, len %u", type, attr->nla_len); - if (mnl_attr_type_valid(attr, attr_max) < 0) { - IF_D(debug, "attr type: %u INVALID", type); - return MNL_CB_ERROR; - } - if (mnl_attr_validate(attr, policy[type].type) < 0) { - IF_D(debug, "attr type: %u POLICY, attrlen %u", type, - mnl_attr_get_payload_len(attr)); - return MNL_CB_ERROR; - } - if (policy[type].type == MNL_TYPE_NUL_STRING && - mnl_attr_get_payload_len(attr) > IPSET_MAXNAMELEN) - return MNL_CB_ERROR; - tb[type] = attr; - return MNL_CB_OK; -} - -static int -create_attr_cb(const struct nlattr *attr, void *data) -{ - return generic_data_attr_cb(attr, data, - IPSET_ATTR_CREATE_MAX, create_attrs); -} - -static int -adt_attr_cb(const struct nlattr *attr, void *data) -{ - return generic_data_attr_cb(attr, data, - IPSET_ATTR_ADT_MAX, adt_attrs); -} - -static int -ipaddr_attr_cb(const struct nlattr *attr, void *data) -{ - return generic_data_attr_cb(attr, data, - IPSET_ATTR_IPADDR_MAX, ipaddr_attrs); -} - -#define FAILURE(format, args...) \ - { ipset_err(session, format , ## args); return MNL_CB_ERROR; } - -static int -attr2data(struct ipset_session *session, struct nlattr *nla[], - int type, const struct ipset_attr_policy attrs[]) -{ - struct ipset_data *data = session->data; - const struct ipset_attr_policy *attr; - const void *d; - int ret; - - attr = &attrs[type]; - d = mnl_attr_get_payload(nla[type]); - - if (attr->type == MNL_TYPE_NESTED && attr->opt) { - /* IP addresses */ - struct nlattr *ipattr[IPSET_ATTR_IPADDR_MAX+1] = {}; - uint8_t family = ipset_data_family(data); - int atype; - D("attr type %u", type); - if (mnl_attr_parse_nested(nla[type], - ipaddr_attr_cb, ipattr) < 0) - FAILURE("Broken kernel message, cannot validate " - "IP address attribute!"); - - /* Validate by hand */ - switch (family) { - case NFPROTO_IPV4: - atype = IPSET_ATTR_IPADDR_IPV4; - if (!ipattr[atype]) - FAILURE("Broken kernel message: IPv4 address " - "expected but not received!"); - if (ipattr[atype]->nla_len < sizeof(uint32_t)) - FAILURE("Broken kernel message: " - "cannot validate IPv4 " - "address attribute!"); - break; - case NFPROTO_IPV6: - atype = IPSET_ATTR_IPADDR_IPV6; - if (!ipattr[atype]) - FAILURE("Broken kernel message: IPv6 address " - "expected but not received!"); - if (ipattr[atype]->nla_len < sizeof(struct in6_addr)) - FAILURE("Broken kernel message: " - "cannot validate IPv6 " - "address attribute!"); - break; - default: - FAILURE("Broken kernel message: " - "IP address attribute but " - "family is unspecified!"); - } - d = mnl_attr_get_payload(ipattr[atype]); - } else if (nla[type]->nla_type & NLA_F_NET_BYTEORDER) { - switch (attr->type) { - case MNL_TYPE_U32: { - uint32_t value; - - value = ntohl(*(const uint32_t *)d); - - d = &value; - break; - } - case MNL_TYPE_U16: { - uint16_t value; - - value = ntohs(*(const uint16_t *)d); - - d = &value; - break; - } - default: - break; - } - } -#ifdef IPSET_DEBUG - if (type == IPSET_ATTR_TYPENAME) - D("nla typename %s", (const char *) d); -#endif - ret = ipset_data_set(data, attr->opt, d); -#ifdef IPSET_DEBUG - if (type == IPSET_ATTR_TYPENAME) - D("nla typename %s", - (const char *) ipset_data_get(data, IPSET_OPT_TYPENAME)); -#endif - return ret; -} - -#define ATTR2DATA(session, nla, type, attrs) \ - if (attr2data(session, nla, type, attrs) < 0) \ - return MNL_CB_ERROR - -static const char cmd2name[][9] = { - [IPSET_CMD_NONE] = "NONE", - [IPSET_CMD_CREATE] = "CREATE", - [IPSET_CMD_DESTROY] = "DESTROY", - [IPSET_CMD_FLUSH] = "FLUSH", - [IPSET_CMD_RENAME] = "RENAME", - [IPSET_CMD_SWAP] = "SWAP", - [IPSET_CMD_LIST] = "LIST", - [IPSET_CMD_SAVE] = "SAVE", - [IPSET_CMD_ADD] = "ADD", - [IPSET_CMD_DEL] = "DEL", - [IPSET_CMD_TEST] = "TEST", - [IPSET_CMD_HEADER] = "HEADER", - [IPSET_CMD_TYPE] = "TYPE", - [IPSET_CMD_PROTOCOL] = "PROTOCOL", -}; - -static inline int -call_outfn(struct ipset_session *session) -{ - int ret = session->outfn("%s", session->outbuf); - - session->outbuf[0] = '\0'; - - return ret < 0 ? ret : 0; -} - -/* Handle printing failures */ -static jmp_buf printf_failure; - -static int __attribute__((format(printf, 2, 3))) -safe_snprintf(struct ipset_session *session, const char *fmt, ...) -{ - va_list args; - int len, ret, loop = 0; - -retry: - len = strlen(session->outbuf); - D("len: %u, retry %u", len, loop); - va_start(args, fmt); - ret = vsnprintf(session->outbuf + len, IPSET_OUTBUFLEN - len, - fmt, args); - va_end(args); - - if (ret < 0) { - ipset_err(session, - "Internal error at printing to output buffer"); - longjmp(printf_failure, 1); - } - - if (ret >= IPSET_OUTBUFLEN - len) { - /* Buffer was too small, push it out and retry */ - D("print buffer and try again: %u", len); - if (loop++) { - ipset_err(session, - "Internal error at printing, loop detected!"); - longjmp(printf_failure, 1); - } - - session->outbuf[len] = '\0'; - if (!call_outfn(session)) - goto retry; - } - return ret; -} - -static int -safe_dprintf(struct ipset_session *session, ipset_printfn fn, - enum ipset_opt opt) -{ - int len, ret, loop = 0; - -retry: - len = strlen(session->outbuf); - D("len: %u, retry %u", len, loop); - ret = fn(session->outbuf + len, IPSET_OUTBUFLEN - len, - session->data, opt, session->envopts); - - if (ret < 0) { - ipset_err(session, - "Internal error at printing to output buffer"); - longjmp(printf_failure, 1); - } - - if (ret >= IPSET_OUTBUFLEN - len) { - /* Buffer was too small, push it out and retry */ - D("print buffer and try again: %u", len); - if (loop++) { - ipset_err(session, - "Internal error at printing, loop detected!"); - longjmp(printf_failure, 1); - } - - session->outbuf[len] = '\0'; - if (!call_outfn(session)) - goto retry; - } - return ret; -} - -static int -list_adt(struct ipset_session *session, struct nlattr *nla[]) -{ - const struct ipset_data *data = session->data; - const struct ipset_type *type; - const struct ipset_arg *arg; - uint8_t family; - int i, found = 0; - - D("enter"); - /* Check and load type, family */ - if (!ipset_data_test(data, IPSET_OPT_TYPE)) - type = ipset_type_get(session, IPSET_CMD_ADD); - else - type = ipset_data_get(data, IPSET_OPT_TYPE); - - if (type == NULL) - return MNL_CB_ERROR; - family = ipset_data_family(data); - - for (i = IPSET_ATTR_UNSPEC + 1; i <= IPSET_ATTR_ADT_MAX; i++) - if (nla[i]) { - found++; - ATTR2DATA(session, nla, i, adt_attrs); - } - D("attr found %u", found); - if (!found) - return MNL_CB_OK; - - switch (session->mode) { - case IPSET_LIST_SAVE: - safe_snprintf(session, "add %s ", ipset_data_setname(data)); - break; - case IPSET_LIST_XML: - safe_snprintf(session, " "); - break; - case IPSET_LIST_PLAIN: - default: - break; - } - - safe_dprintf(session, ipset_print_elem, IPSET_OPT_ELEM); - - for (arg = type->args[IPSET_ADD]; arg != NULL && arg->print; arg++) { - if (!ipset_data_test(data, arg->opt)) - continue; - switch (session->mode) { - case IPSET_LIST_SAVE: - case IPSET_LIST_PLAIN: - safe_snprintf(session, " %s ", arg->name[0]); - if (arg->has_arg == IPSET_NO_ARG) - break; - safe_dprintf(session, arg->print, arg->opt); - break; - case IPSET_LIST_XML: - if (arg->has_arg == IPSET_NO_ARG) { - safe_snprintf(session, - " <%s/>\n", - arg->name[0]); - break; - } - safe_snprintf(session, " <%s>", - arg->name[0]); - safe_dprintf(session, arg->print, arg->opt); - safe_snprintf(session, "\n", - arg->name[0]); - break; - default: - break; - } - } - - if (session->mode == IPSET_LIST_XML) - safe_snprintf(session, "\n"); - else - safe_snprintf(session, "\n"); - - return MNL_CB_OK; -} - -#define FAMILY_TO_STR(f) \ - ((f) == NFPROTO_IPV4 ? "inet" : \ - (f) == NFPROTO_IPV6 ? "inet6" : "any") - -static int -list_create(struct ipset_session *session, struct nlattr *nla[]) -{ - const struct ipset_data *data = session->data; - const struct ipset_type *type; - const struct ipset_arg *arg; - uint8_t family; - int i; - - for (i = IPSET_ATTR_UNSPEC + 1; i <= IPSET_ATTR_CREATE_MAX; i++) - if (nla[i]) { - D("add attr %u, opt %u", i, create_attrs[i].opt); - ATTR2DATA(session, nla, i, create_attrs); - } - - type = ipset_type_check(session); - if (type == NULL) - return MNL_CB_ERROR; - family = ipset_data_family(data); - - switch (session->mode) { - case IPSET_LIST_SAVE: - safe_snprintf(session, "create %s %s ", - ipset_data_setname(data), - type->name); - break; - case IPSET_LIST_PLAIN: - safe_snprintf(session, "%sName: %s\n" - "Type: %s\nHeader: ", - session->printed_set ? "\n" : "", - ipset_data_setname(data), - type->name); - break; - case IPSET_LIST_XML: - safe_snprintf(session, - "\n" - " %s\n" - "
\n", - ipset_data_setname(data), - type->name); - break; - default: - break; - } - - for (arg = type->args[IPSET_CREATE]; arg != NULL && arg->opt; arg++) { - if (!arg->print || - !ipset_data_test(data, arg->opt) || - (arg->opt == IPSET_OPT_FAMILY && - family == type->family)) - continue; - switch (session->mode) { - case IPSET_LIST_SAVE: - case IPSET_LIST_PLAIN: - safe_snprintf(session, "%s ", arg->name[0]); - if (arg->has_arg == IPSET_NO_ARG) - break; - safe_dprintf(session, arg->print, arg->opt); - safe_snprintf(session, " "); - break; - case IPSET_LIST_XML: - if (arg->has_arg == IPSET_NO_ARG) { - safe_snprintf(session, - " <%s/>\n", - arg->name[0]); - break; - } - safe_snprintf(session, " <%s>", - arg->name[0]); - safe_dprintf(session, arg->print, arg->opt); - safe_snprintf(session, "\n", - arg->name[0]); - break; - default: - break; - } - } - switch (session->mode) { - case IPSET_LIST_SAVE: - safe_snprintf(session, "\n"); - break; - case IPSET_LIST_PLAIN: - safe_snprintf(session, "\nSize in memory: "); - safe_dprintf(session, ipset_print_number, IPSET_OPT_MEMSIZE); - safe_snprintf(session, "\nReferences: "); - safe_dprintf(session, ipset_print_number, IPSET_OPT_REFERENCES); - safe_snprintf(session, - session->envopts & IPSET_ENV_LIST_HEADER ? - "\n" : "\nMembers:\n"); - break; - case IPSET_LIST_XML: - safe_snprintf(session, " "); - safe_dprintf(session, ipset_print_number, IPSET_OPT_MEMSIZE); - safe_snprintf(session, "\n "); - safe_dprintf(session, ipset_print_number, IPSET_OPT_REFERENCES); - safe_snprintf(session, - session->envopts & IPSET_ENV_LIST_HEADER ? - "\n
\n" : - "\n \n \n"); - break; - default: - break; - } - session->printed_set++; - - return MNL_CB_OK; -} - -static int -print_set_done(struct ipset_session *session) -{ - D("called for %s", session->saved_setname[0] == '\0' - ? "NONE" : session->saved_setname); - switch (session->mode) { - case IPSET_LIST_XML: - if (session->envopts & IPSET_ENV_LIST_SETNAME) - break; - if (session->envopts & IPSET_ENV_LIST_HEADER) { - if (session->saved_setname[0] != '\0') - safe_snprintf(session, "
\n"); - break; - } - if (session->saved_setname[0] != '\0') - safe_snprintf(session, " \n\n"); - break; - default: - break; - } - return call_outfn(session) ? MNL_CB_ERROR : MNL_CB_STOP; -} - -static int -callback_list(struct ipset_session *session, struct nlattr *nla[], - enum ipset_cmd cmd) -{ - struct ipset_data *data = session->data; - - if (setjmp(printf_failure)) { - session->saved_setname[0] = '\0'; - session->printed_set = 0; - return MNL_CB_ERROR; - } - - if (!nla[IPSET_ATTR_SETNAME]) - FAILURE("Broken %s kernel message: missing setname!", - cmd2name[cmd]); - - ATTR2DATA(session, nla, IPSET_ATTR_SETNAME, cmd_attrs); - D("setname %s", ipset_data_setname(data)); - if (session->envopts & IPSET_ENV_LIST_SETNAME && - session->mode != IPSET_LIST_SAVE) { - if (session->mode == IPSET_LIST_XML) - safe_snprintf(session, "\n", - ipset_data_setname(data)); - else - safe_snprintf(session, "%s\n", - ipset_data_setname(data)); - return call_outfn(session) ? MNL_CB_ERROR : MNL_CB_OK; - } - - if (STREQ(ipset_data_setname(data), session->saved_setname)) { - /* Header part already seen */ - if (ipset_data_test(data, IPSET_OPT_TYPE) && - nla[IPSET_ATTR_DATA] != NULL) - FAILURE("Broken %s kernel message: " - "extra DATA received!", cmd2name[cmd]); - } else { - if (nla[IPSET_ATTR_DATA] == NULL) - FAILURE("Broken %s kernel message: " - "missing DATA part!", cmd2name[cmd]); - - /* Close previous set printing */ - if (session->saved_setname[0] != '\0') - print_set_done(session); - } - - if (nla[IPSET_ATTR_DATA] != NULL) { - struct nlattr *cattr[IPSET_ATTR_CREATE_MAX+1] = {}; - - if (!(nla[IPSET_ATTR_TYPENAME] && - nla[IPSET_ATTR_FAMILY] && - nla[IPSET_ATTR_REVISION])) - FAILURE("Broken %s kernel message: missing %s!", - cmd2name[cmd], - !nla[IPSET_ATTR_TYPENAME] ? "typename" : - !nla[IPSET_ATTR_FAMILY] ? "family" : - "revision"); - - /* Reset CREATE specific flags */ - ipset_data_flags_unset(data, IPSET_CREATE_FLAGS); - D("nla typename %s", - (char *) mnl_attr_get_payload(nla[IPSET_ATTR_TYPENAME])); - D("nla typename %s", - (char *) mnl_attr_get_payload(nla[IPSET_ATTR_TYPENAME])); - ATTR2DATA(session, nla, IPSET_ATTR_FAMILY, cmd_attrs); - ATTR2DATA(session, nla, IPSET_ATTR_TYPENAME, cmd_attrs); - ATTR2DATA(session, nla, IPSET_ATTR_REVISION, cmd_attrs); - D("head: family %u, typename %s", - ipset_data_family(data), - (const char *) ipset_data_get(data, IPSET_OPT_TYPENAME)); - if (mnl_attr_parse_nested(nla[IPSET_ATTR_DATA], - create_attr_cb, cattr) < 0) - FAILURE("Broken %s kernel message: " - "cannot validate DATA attributes!", - cmd2name[cmd]); - if (list_create(session, cattr) != MNL_CB_OK) - return MNL_CB_ERROR; - strcpy(session->saved_setname, ipset_data_setname(data)); - } - - if (nla[IPSET_ATTR_ADT] != NULL) { - struct nlattr *tb, *adt[IPSET_ATTR_ADT_MAX+1]; - - mnl_attr_for_each_nested(tb, nla[IPSET_ATTR_ADT]) { - D("ADT attributes for %s", ipset_data_setname(data)); - memset(adt, 0, sizeof(adt)); - /* Reset ADT specific flags */ - ipset_data_flags_unset(data, IPSET_ADT_FLAGS); - if (mnl_attr_parse_nested(tb, adt_attr_cb, adt) < 0) - FAILURE("Broken %s kernel message: " - "cannot validate ADT attributes!", - cmd2name[cmd]); - if (list_adt(session, adt) != MNL_CB_OK) - return MNL_CB_ERROR; - } - } - return call_outfn(session) ? MNL_CB_ERROR : MNL_CB_OK; -} - -#ifndef IPSET_PROTOCOL_MIN -#define IPSET_PROTOCOL_MIN IPSET_PROTOCOL -#endif - -#ifndef IPSET_PROTOCOL_MAX -#define IPSET_PROTOCOL_MAX IPSET_PROTOCOL -#endif - -static int -callback_version(struct ipset_session *session, struct nlattr *nla[]) -{ - uint8_t min, max; - - min = max = mnl_attr_get_u8(nla[IPSET_ATTR_PROTOCOL]); - - if (nla[IPSET_ATTR_PROTOCOL_MIN]) { - min = mnl_attr_get_u8(nla[IPSET_ATTR_PROTOCOL_MIN]); - D("min: %u", min); - } - - if (min > IPSET_PROTOCOL_MAX || max < IPSET_PROTOCOL_MIN) - FAILURE("Cannot communicate with kernel: " - "Kernel support protocol versions %u-%u " - "while userspace supports protocol versions %u-%u", - min, max, IPSET_PROTOCOL_MIN, IPSET_PROTOCOL_MAX); - - if (!(session->envopts & IPSET_ENV_QUIET) && - max != IPSET_PROTOCOL_MAX) - ipset_warn(session, - "Kernel support protocol versions %u-%u " - "while userspace supports protocol versions %u-%u", - min, max, IPSET_PROTOCOL_MIN, IPSET_PROTOCOL_MAX); - - session->version_checked = true; - - return MNL_CB_STOP; -} - -static int -callback_header(struct ipset_session *session, struct nlattr *nla[]) -{ - const char *setname; - const struct ipset_data *data = session->data; - - if (!nla[IPSET_ATTR_SETNAME]) - FAILURE("Broken HEADER kernel message: missing setname!"); - - setname = mnl_attr_get_str(nla[IPSET_ATTR_SETNAME]); - if (!STREQ(setname, ipset_data_setname(data))) - FAILURE("Broken HEADER kernel message: sent setname `%s' " - "does not match with received one `%s'!", - ipset_data_setname(data), setname); - - if (!(nla[IPSET_ATTR_TYPENAME] && - nla[IPSET_ATTR_REVISION] && - nla[IPSET_ATTR_FAMILY])) - FAILURE("Broken HEADER kernel message: " - "missing attribute '%s'!", - !nla[IPSET_ATTR_TYPENAME] ? "typename" : - !nla[IPSET_ATTR_REVISION] ? "revision" : - "family"); - - ATTR2DATA(session, nla, IPSET_ATTR_TYPENAME, cmd_attrs); - ATTR2DATA(session, nla, IPSET_ATTR_REVISION, cmd_attrs); - ATTR2DATA(session, nla, IPSET_ATTR_FAMILY, cmd_attrs); - D("got family: %u", ipset_data_family(session->data)); - - return MNL_CB_STOP; -} - -static int -callback_type(struct ipset_session *session, struct nlattr *nla[]) -{ - const struct ipset_data *data = session->data; - const char *typename, *orig; - - if (!(nla[IPSET_ATTR_TYPENAME] && - nla[IPSET_ATTR_REVISION] && - nla[IPSET_ATTR_FAMILY])) - FAILURE("Broken TYPE kernel message: " - "missing attribute '%s'!", - !nla[IPSET_ATTR_TYPENAME] ? "typename" : - !nla[IPSET_ATTR_REVISION] ? "revision" : - "family"); - - typename = mnl_attr_get_str(nla[IPSET_ATTR_TYPENAME]); - orig = ipset_data_get(data, IPSET_OPT_TYPENAME); - if (!STREQ(typename, orig)) - FAILURE("Broken TYPE kernel message: sent typename `%s' " - "does not match with received one `%s'!", - orig, typename); - - ATTR2DATA(session, nla, IPSET_ATTR_TYPENAME, cmd_attrs); - ATTR2DATA(session, nla, IPSET_ATTR_REVISION, cmd_attrs); - ATTR2DATA(session, nla, IPSET_ATTR_FAMILY, cmd_attrs); - if (nla[IPSET_ATTR_REVISION_MIN]) - ATTR2DATA(session, nla, IPSET_ATTR_REVISION_MIN, cmd_attrs); - - return MNL_CB_STOP; -} - -static int -cmd_attr_cb(const struct nlattr *attr, void *data) -{ - return generic_data_attr_cb(attr, data, IPSET_ATTR_CMD_MAX, cmd_attrs); -} - -#if 0 -static int -mnl_attr_parse_dbg(const struct nlmsghdr *nlh, int offset, - mnl_attr_cb_t cb, void *data) -{ - int ret = MNL_CB_OK; - struct nlattr *attr = mnl_nlmsg_get_payload_offset(nlh, offset); - int len = nlh->nlmsg_len - MNL_NLMSG_HDRLEN - MNL_ALIGN(offset); - - while (mnl_attr_ok(attr, len)) { - D("attr: type %u, attrlen %u, len %u", - mnl_attr_get_type(attr), attr->nla_len, len); - if (cb && (ret = cb(attr, data)) <= MNL_CB_STOP) - return ret; - attr = mnl_attr_next(attr, &len); - } - return ret; -} -#endif - -static int -callback_data(const struct nlmsghdr *nlh, void *data) -{ - struct ipset_session *session = data; - struct nlattr *nla[IPSET_ATTR_CMD_MAX+1] = {}; - uint8_t proto, cmd; - int ret = MNL_CB_OK, nfmsglen = MNL_ALIGN(sizeof(struct genlmsghdr)); - - D("called, nlmsg_len %u", nlh->nlmsg_len); - cmd = ipset_get_nlmsg_type(nlh); - if (cmd == IPSET_CMD_LIST && session->cmd == IPSET_CMD_SAVE) - /* Kernel always send IPSET_CMD_LIST */ - cmd = IPSET_CMD_SAVE; - - if (cmd != session->cmd) - FAILURE("Protocol error, we sent command %s " - "and received %s[%u]", - cmd2name[session->cmd], - cmd < IPSET_MSG_MAX ? cmd2name[cmd] : "unknown", cmd); - - if (mnl_attr_parse(nlh, nfmsglen, cmd_attr_cb, nla) < MNL_CB_STOP) - FAILURE("Broken %s kernel message: " - "cannot validate and parse attributes", - cmd2name[cmd]); - - if (!nla[IPSET_ATTR_PROTOCOL]) - FAILURE("Sad, sad day: kernel message %s " - "does not carry the protocol version.", - cmd2name[cmd]); - - proto = mnl_attr_get_u8(nla[IPSET_ATTR_PROTOCOL]); - - /* Check protocol */ - if (cmd != IPSET_CMD_PROTOCOL && proto != IPSET_PROTOCOL) - FAILURE("Giving up: kernel protocol version %u " - "does not match our protocol version %u", - proto, IPSET_PROTOCOL); - - D("Message: %s", cmd2name[cmd]); - switch (cmd) { - case IPSET_CMD_LIST: - case IPSET_CMD_SAVE: - ret = callback_list(session, nla, cmd); - D("flag multi: %u", nlh->nlmsg_flags & NLM_F_MULTI); - if (ret >= MNL_CB_STOP && !(nlh->nlmsg_flags & NLM_F_MULTI)) - ret = print_set_done(session); - break; - case IPSET_CMD_PROTOCOL: - if (!session->version_checked) - ret = callback_version(session, nla); - break; - case IPSET_CMD_HEADER: - ret = callback_header(session, nla); - break; - case IPSET_CMD_TYPE: - ret = callback_type(session, nla); - break; - default: - FAILURE("Data message received when not expected at %s", - cmd2name[session->cmd]); - } - D("return code: %s", ret == MNL_CB_STOP ? "stop" : - ret == MNL_CB_OK ? "ok" : "error"); - return ret; -} - -static int -callback_done(const struct nlmsghdr *nlh UNUSED, void *data) -{ - struct ipset_session *session = data; - - D(" called"); - if (session->cmd == IPSET_CMD_LIST || session->cmd == IPSET_CMD_SAVE) - return print_set_done(session); - - FAILURE("Invalid message received in non LIST or SAVE state."); -} - -static int -decode_errmsg(struct ipset_session *session, const struct nlmsghdr *nlh) -{ - const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh); - const struct nlmsghdr *msg = &err->msg; - struct nlattr *nla[IPSET_ATTR_CMD_MAX+1] = {}; - enum ipset_cmd cmd; - int nfmsglen = MNL_ALIGN(sizeof(struct genlmsghdr)); - - if (nlh->nlmsg_len < (uint32_t) MNL_ALIGN(sizeof(struct nlmsgerr)) - || nlh->nlmsg_len < MNL_ALIGN(sizeof(struct nlmsgerr)) - + msg->nlmsg_len) - FAILURE("Broken error report message received."); - - cmd = ipset_get_nlmsg_type(msg); - D("nlsmg_len: %u", msg->nlmsg_len); - if (cmd != session->cmd) - FAILURE("Protocol error, we sent command %s " - "and received error report for %s[%u]", - cmd2name[session->cmd], - cmd < IPSET_MSG_MAX ? cmd2name[cmd] : "unknown", cmd); - - if (mnl_attr_parse(msg, nfmsglen, cmd_attr_cb, nla) < MNL_CB_STOP) - FAILURE("Broken %s error report message: " - "cannot validate attributes", - cmd2name[cmd]); - - if (!nla[IPSET_ATTR_PROTOCOL]) - FAILURE("Broken %s error report message: " - "missing protocol attribute", - cmd2name[cmd]); - - if (nla[IPSET_ATTR_LINENO]) { - session->lineno = mnl_attr_get_u32(nla[IPSET_ATTR_LINENO]); - if (nla[IPSET_ATTR_LINENO]->nla_type & NLA_F_NET_BYTEORDER) - session->lineno = ntohl(session->lineno); - } - - return ipset_errcode(session, cmd, -err->error); -} - -static int -callback_error(const struct nlmsghdr *nlh, void *cbdata) -{ - struct ipset_session *session = cbdata; - struct ipset_data *data = session->data; - const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh); - int ret = MNL_CB_ERROR; - - D(" called, cmd %s", cmd2name[session->cmd]); - if (nlh->nlmsg_len < mnl_nlmsg_size(sizeof(struct nlmsgerr))) - FAILURE("Broken error message received."); - - if (err->error == 0) { - /* ACK */ - ret = MNL_CB_STOP; - - switch (session->cmd) { - case IPSET_CMD_CREATE: - /* Add successfully created set to the cache */ - ipset_cache_add(ipset_data_setname(data), - ipset_data_get(data, IPSET_OPT_TYPE), - ipset_data_family(data)); - break; - case IPSET_CMD_DESTROY: - /* Delete destroyed sets from the cache */ - ipset_cache_del(ipset_data_setname(data)); - /* Fall through */ - case IPSET_CMD_FLUSH: - break; - case IPSET_CMD_RENAME: - ipset_cache_rename(ipset_data_setname(data), - ipset_data_get(data, - IPSET_OPT_SETNAME2)); - break; - case IPSET_CMD_SWAP: - ipset_cache_swap(ipset_data_setname(data), - ipset_data_get(data, - IPSET_OPT_SETNAME2)); - break; - case IPSET_CMD_TEST: - if (!(session->envopts & IPSET_ENV_QUIET)) { - ipset_print_elem(session->report, - IPSET_ERRORBUFLEN, - session->data, - IPSET_OPT_NONE, 0); - ipset_warn(session, " is in set %s.", - ipset_data_setname(data)); - } - /* Fall through */ - case IPSET_CMD_ADD: - case IPSET_CMD_DEL: - break; - case IPSET_CMD_LIST: - case IPSET_CMD_SAVE: - /* No set in kernel */ - print_set_done(session); - break; - default: - FAILURE("ACK message received to command %s[%u], " - "which is not expected", - session->cmd < IPSET_MSG_MAX - ? cmd2name[session->cmd] : "unknown", - session->cmd); - } - return ret; - } - D("nlmsgerr error: %u", -err->error); - - /* Error messages */ - - /* Special case for IPSET_CMD_TEST */ - if (session->cmd == IPSET_CMD_TEST && - err->error == -IPSET_ERR_EXIST) { - if (!(session->envopts & IPSET_ENV_QUIET)) { - ipset_print_elem(session->report, IPSET_ERRORBUFLEN, - session->data, IPSET_OPT_NONE, 0); - ipset_warn(session, " is NOT in set %s.", - ipset_data_setname(data)); - } - return ret; - } - - decode_errmsg(session, nlh); - - return ret; -} - -static int -callback_noop(const struct nlmsghdr *nlh UNUSED, void *data UNUSED) -{ - return MNL_CB_OK; -} -/* - * Build and send messages - */ - -static inline int -open_nested(struct ipset_session *session, struct nlmsghdr *nlh, int attr) -{ - if (nlh->nlmsg_len + MNL_ATTR_HDRLEN > session->bufsize) - return 1; - session->nested[session->nestid++] = mnl_attr_nest_start(nlh, attr); - return 0; -} - -static inline void -close_nested(struct ipset_session *session, struct nlmsghdr *nlh) -{ - mnl_attr_nest_end(nlh, session->nested[session->nestid-1]); - session->nested[--session->nestid] = NULL; -} - -static size_t -attr_len(const struct ipset_attr_policy *attr, uint8_t family, uint16_t *flags) -{ - switch (attr->type) { - case MNL_TYPE_NESTED: - if (attr->len) - return attr->len; - - *flags = NLA_F_NET_BYTEORDER; - return family == NFPROTO_IPV4 ? sizeof(uint32_t) - : sizeof(struct in6_addr); - case MNL_TYPE_U32: - *flags = NLA_F_NET_BYTEORDER; - return sizeof(uint32_t); - case MNL_TYPE_U16: - *flags = NLA_F_NET_BYTEORDER; - return sizeof(uint16_t); - case MNL_TYPE_U8: - return sizeof(uint8_t); - default: - return attr->len; - } -} - -#define BUFFER_FULL(bufsize, nlmsg_len, nestlen, attrlen) \ -(nlmsg_len + nestlen + MNL_ATTR_HDRLEN + MNL_ALIGN(alen) + \ - MNL_ALIGN(sizeof(struct nlmsgerr)) > bufsize) - -static int -rawdata2attr(struct ipset_session *session, struct nlmsghdr *nlh, - const void *d, int type, uint8_t family, - const struct ipset_attr_policy attrs[]) -{ - const struct ipset_attr_policy *attr; - int alen; - uint16_t flags = 0; - - - attr = &attrs[type]; - if (attr->type == MNL_TYPE_NESTED) { - /* IP addresses */ - struct nlattr *nested; - int atype = family == NFPROTO_IPV4 ? IPSET_ATTR_IPADDR_IPV4 - : IPSET_ATTR_IPADDR_IPV6; - - alen = attr_len(attr, family, &flags); - if (BUFFER_FULL(session->bufsize, nlh->nlmsg_len, - MNL_ATTR_HDRLEN, alen)) - return 1; - nested = mnl_attr_nest_start(nlh, type); - D("family: %s", family == NFPROTO_IPV4 ? "INET" : - family == NFPROTO_IPV6 ? "INET6" : "UNSPEC"); - mnl_attr_put(nlh, atype | flags, alen, d); - mnl_attr_nest_end(nlh, nested); - - return 0; - } - - alen = attr_len(attr, family, &flags); - if (BUFFER_FULL(session->bufsize, nlh->nlmsg_len, 0, alen)) - return 1; - - switch (attr->type) { - case MNL_TYPE_NUL_STRING: - alen = strlen((const char *)d) + 1; - break; - case MNL_TYPE_U32: { - uint32_t value = htonl(*(const uint32_t *)d); - - d = &value; - break; - } - case MNL_TYPE_U16: { - uint16_t value = htons(*(const uint16_t *)d); - - d = &value; - break; - } - default: - break; - } - - mnl_attr_put(nlh, type | flags, alen, d); - - return 0; -} - -static int -data2attr(struct ipset_session *session, struct nlmsghdr *nlh, - struct ipset_data *data, int type, uint8_t family, - const struct ipset_attr_policy attrs[]) -{ - const struct ipset_attr_policy *attr = &attrs[type]; - - return rawdata2attr(session, nlh, ipset_data_get(data, attr->opt), - type, family, attrs); -} - -#define ADDATTR_PROTOCOL(nlh) \ - mnl_attr_put_u8(nlh, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL) - -#define ADDATTR(session, nlh, data, type, family, attrs) \ - data2attr(session, nlh, data, type, family, attrs) - -#define ADDATTR_SETNAME(session, nlh, data) \ - data2attr(session, nlh, data, IPSET_ATTR_SETNAME, NFPROTO_IPV4, cmd_attrs) - -#define ADDATTR_IF(session, nlh, data, type, family, attrs) \ - ipset_data_test(data, attrs[type].opt) ? \ - data2attr(session, nlh, data, type, family, attrs) : 0 - -#define ADDATTR_RAW(session, nlh, data, type, attrs) \ - rawdata2attr(session, nlh, data, type, NFPROTO_IPV4, attrs) - -static void -addattr_create(struct ipset_session *session, - struct nlmsghdr *nlh, struct ipset_data *data, uint8_t family) -{ - int i; - - for (i = IPSET_ATTR_UNSPEC + 1; i <= IPSET_ATTR_CREATE_MAX; i++) - ADDATTR_IF(session, nlh, data, i, family, create_attrs); -} - -static int -addattr_adt(struct ipset_session *session, - struct nlmsghdr *nlh, struct ipset_data *data, uint8_t family) -{ - int i; - - for (i = IPSET_ATTR_UNSPEC + 1; i <= IPSET_ATTR_ADT_MAX; i++) - if (ADDATTR_IF(session, nlh, data, i, family, adt_attrs)) - return 1; - return 0; -} - -#define PRIVATE_MSG_BUFLEN 256 - -static int -build_send_private_msg(struct ipset_session *session, enum ipset_cmd cmd) -{ - char buffer[PRIVATE_MSG_BUFLEN] __attribute__ ((aligned)) = {}; - struct nlmsghdr *nlh = (void *)buffer; - struct ipset_data *data = session->data; - int len = PRIVATE_MSG_BUFLEN, ret; - enum ipset_cmd saved = session->cmd; - - /* Initialize header */ - session->transport->fill_hdr(session->handle, cmd, buffer, len, 0); - - ADDATTR_PROTOCOL(nlh); - - switch (cmd) { - case IPSET_CMD_PROTOCOL: - break; - case IPSET_CMD_HEADER: - if (!ipset_data_test(data, IPSET_SETNAME)) - return ipset_err(session, - "Invalid internal HEADER command: " - "missing setname"); - ADDATTR_SETNAME(session, nlh, data); - break; - case IPSET_CMD_TYPE: - if (!ipset_data_test(data, IPSET_OPT_TYPENAME)) - return ipset_err(session, - "Invalid internal TYPE command: " - "missing settype"); - ADDATTR(session, nlh, data, IPSET_ATTR_TYPENAME, - NFPROTO_IPV4, cmd_attrs); - if (ipset_data_test(data, IPSET_OPT_FAMILY)) - ADDATTR(session, nlh, data, IPSET_ATTR_FAMILY, - NFPROTO_IPV4, cmd_attrs); - else - /* bitmap:port and list:set types */ - mnl_attr_put_u8(nlh, IPSET_ATTR_FAMILY, NFPROTO_UNSPEC); - break; - default: - return ipset_err(session, "Internal error: " - "unknown private command %u", cmd); - } - - /* Backup, then restore real command */ - session->cmd = cmd; - ret = session->transport->query(session->handle, buffer, len); - session->cmd = saved; - - return ret; -} - -static inline bool -may_aggregate_ad(struct ipset_session *session, enum ipset_cmd cmd) -{ - return session->lineno != 0 && - (cmd == IPSET_CMD_ADD || cmd == IPSET_CMD_DEL) && - cmd == session->cmd && - STREQ(ipset_data_setname(session->data), session->saved_setname); -} - -static int -build_msg(struct ipset_session *session, bool aggregate) -{ - struct nlmsghdr *nlh = session->buffer; - struct ipset_data *data = session->data; - - /* Public commands */ - D("cmd %s, nlmsg_len: %u", cmd2name[session->cmd], nlh->nlmsg_len); - if (nlh->nlmsg_len == 0) { - /* Initialize header */ - aggregate = false; - session->transport->fill_hdr(session->handle, - session->cmd, - session->buffer, - session->bufsize, - session->envopts); - ADDATTR_PROTOCOL(nlh); - } - D("Protocol added, aggregate %s", aggregate ? "yes" : "no"); - switch (session->cmd) { - case IPSET_CMD_CREATE: { - const struct ipset_type *type; - - /* Sanity checkings */ - if (!ipset_data_test(data, IPSET_SETNAME)) - return ipset_err(session, - "Invalid create command: missing setname"); - if (!ipset_data_test(data, IPSET_OPT_TYPE)) - return ipset_err(session, - "Invalid create command: missing settype"); - - type = ipset_data_get(data, IPSET_OPT_TYPE); - /* Core attributes: - * setname, typename, revision, family, flags (optional) */ - ADDATTR_SETNAME(session, nlh, data); - ADDATTR(session, nlh, data, IPSET_ATTR_TYPENAME, - NFPROTO_IPV4, cmd_attrs); - ADDATTR_RAW(session, nlh, &type->revision, - IPSET_ATTR_REVISION, cmd_attrs); - D("family: %u, type family %u", - ipset_data_family(data), type->family); - if (ipset_data_test(data, IPSET_OPT_FAMILY)) - ADDATTR(session, nlh, data, IPSET_ATTR_FAMILY, - NFPROTO_IPV4, cmd_attrs); - else - /* bitmap:port and list:set types */ - mnl_attr_put_u8(nlh, IPSET_ATTR_FAMILY, NFPROTO_UNSPEC); - - /* Type-specific create attributes */ - D("call open_nested"); - open_nested(session, nlh, IPSET_ATTR_DATA); - addattr_create(session, nlh, data, type->family); - D("call close_nested"); - close_nested(session, nlh); - break; - } - case IPSET_CMD_DESTROY: - case IPSET_CMD_FLUSH: - case IPSET_CMD_SAVE: - if (ipset_data_test(data, IPSET_SETNAME)) - ADDATTR_SETNAME(session, nlh, data); - break; - case IPSET_CMD_LIST: { - uint32_t flags = 0; - - if (session->envopts & IPSET_ENV_LIST_SETNAME) - flags |= IPSET_FLAG_LIST_SETNAME; - if (session->envopts & IPSET_ENV_LIST_HEADER) - flags |= IPSET_FLAG_LIST_HEADER; - if (ipset_data_test(data, IPSET_SETNAME)) - ADDATTR_SETNAME(session, nlh, data); - if (flags && session->mode != IPSET_LIST_SAVE) { - ipset_data_set(data, IPSET_OPT_FLAGS, &flags); - ADDATTR(session, nlh, data, IPSET_ATTR_FLAGS, NFPROTO_IPV4, - cmd_attrs); - } - break; - } - case IPSET_CMD_RENAME: - case IPSET_CMD_SWAP: - if (!ipset_data_test(data, IPSET_SETNAME)) - return ipset_err(session, - "Invalid %s command: missing from-setname", - session->cmd == IPSET_CMD_SWAP ? "swap" : - "rename"); - if (!ipset_data_test(data, IPSET_OPT_SETNAME2)) - return ipset_err(session, - "Invalid %s command: missing to-setname", - session->cmd == IPSET_CMD_SWAP ? "swap" : - "rename"); - ADDATTR_SETNAME(session, nlh, data); - ADDATTR_RAW(session, nlh, - ipset_data_get(data, IPSET_OPT_SETNAME2), - IPSET_ATTR_SETNAME2, cmd_attrs); - break; - case IPSET_CMD_ADD: - case IPSET_CMD_DEL: { - const struct ipset_type *type; - - if (!aggregate) { - /* Setname, type not checked/added yet */ - if (!ipset_data_test(data, IPSET_SETNAME)) - return ipset_err(session, - "Invalid %s command: missing setname", - session->cmd == IPSET_CMD_ADD ? "add" : - "del"); - - if (!ipset_data_test(data, IPSET_OPT_TYPE)) - return ipset_err(session, - "Invalid %s command: missing settype", - session->cmd == IPSET_CMD_ADD ? "add" : - "del"); - - /* Core options: setname */ - ADDATTR_SETNAME(session, nlh, data); - if (session->lineno != 0) { - /* Restore mode */ - ADDATTR_RAW(session, nlh, &session->lineno, - IPSET_ATTR_LINENO, cmd_attrs); - open_nested(session, nlh, IPSET_ATTR_ADT); - } - } - type = ipset_data_get(data, IPSET_OPT_TYPE); - D("family: %u, type family %u", - ipset_data_family(data), type->family); - if (open_nested(session, nlh, IPSET_ATTR_DATA)) { - D("open_nested failed"); - return 1; - } - if (addattr_adt(session, nlh, data, ipset_data_family(data)) || - ADDATTR_RAW(session, nlh, &session->lineno, - IPSET_ATTR_LINENO, cmd_attrs)) { - /* Cancel last, unfinished nested attribute */ - mnl_attr_nest_cancel(nlh, - session->nested[session->nestid-1]); - session->nested[--session->nestid] = NULL; - return 1; - } - close_nested(session, nlh); - break; - } - case IPSET_CMD_TEST: { - const struct ipset_type *type; - /* Return codes are not aggregated, so tests cannot be either */ - - /* Setname, type not checked/added yet */ - - if (!ipset_data_test(data, IPSET_SETNAME)) - return ipset_err(session, - "Invalid test command: missing setname"); - - if (!ipset_data_test(data, IPSET_OPT_TYPE)) - return ipset_err(session, - "Invalid test command: missing settype"); - - type = ipset_data_get(data, IPSET_OPT_TYPE); - D("family: %u, type family %u", - ipset_data_family(data), type->family); - ADDATTR_SETNAME(session, nlh, data); - open_nested(session, nlh, IPSET_ATTR_DATA); - addattr_adt(session, nlh, data, ipset_data_family(data)); - close_nested(session, nlh); - break; - } - default: - return ipset_err(session, "Internal error: unknown command %u", - session->cmd); - } - return 0; -} - -/** - * ipset_commit - commit buffered commands - * @session: session structure - * - * Commit buffered commands, if there are any. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_commit(struct ipset_session *session) -{ - struct nlmsghdr *nlh; - int ret = 0, i; - - assert(session); - - nlh = session->buffer; - D("send buffer: len %u, cmd %s", - nlh->nlmsg_len, cmd2name[session->cmd]); - if (nlh->nlmsg_len == 0) - /* Nothing to do */ - return 0; - - /* Close nested data blocks */ - for (i = session->nestid - 1; i >= 0; i--) - close_nested(session, nlh); - - /* Send buffer */ - ret = session->transport->query(session->handle, - session->buffer, - session->bufsize); - - /* Reset saved data and nested state */ - session->saved_setname[0] = '\0'; - session->printed_set = 0; - for (i = session->nestid - 1; i >= 0; i--) - session->nested[i] = NULL; - session->nestid = 0; - nlh->nlmsg_len = 0; - - D("ret: %d", ret); - - if (ret < 0) { - if (session->report[0] != '\0') - return -1; - else - return ipset_err(session, - "Internal protocol error"); - } - return 0; -} - -static mnl_cb_t cb_ctl[] = { - [NLMSG_NOOP] = callback_noop, - [NLMSG_ERROR] = callback_error, - [NLMSG_DONE] = callback_done, - [NLMSG_OVERRUN] = callback_noop, - [NLMSG_MIN_TYPE] = callback_data, -}; - -static inline struct ipset_handle * -init_transport(struct ipset_session *session) -{ - session->handle = session->transport->init(cb_ctl, session); - - return session->handle; -} - -/** - * ipset_cmd - execute a command - * @session: session structure - * @cmd: command to execute - * @lineno: command line number in restore mode - * - * Execute - or prepare/buffer in restore mode - a command. - * It is the caller responsibility that the data field be filled out - * with all required parameters for a successful execution. - * The data field is cleared after this function call for the public - * commands. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_cmd(struct ipset_session *session, enum ipset_cmd cmd, uint32_t lineno) -{ - struct ipset_data *data; - bool aggregate = false; - int ret = -1; - - assert(session); - - if (cmd <= IPSET_CMD_NONE || cmd >= IPSET_MSG_MAX) - return 0; - - /* Initialize transport method if not done yet */ - if (session->handle == NULL && init_transport(session) == NULL) - return ipset_err(session, - "Cannot open session to kernel."); - - data = session->data; - - /* Check protocol version once */ - if (!session->version_checked) { - if (build_send_private_msg(session, IPSET_CMD_PROTOCOL) < 0) - return -1; - } - - /* Private commands */ - if (cmd == IPSET_CMD_TYPE || cmd == IPSET_CMD_HEADER) - return build_send_private_msg(session, cmd); - - /* Check aggregatable commands */ - aggregate = may_aggregate_ad(session, cmd); - if (!aggregate) { - /* Flush possible aggregated commands */ - ret = ipset_commit(session); - if (ret < 0) - return ret; - } - - /* Real command: update lineno too */ - session->cmd = cmd; - session->lineno = lineno; - - /* Set default output mode */ - if (cmd == IPSET_CMD_LIST) { - if (session->mode == IPSET_LIST_NONE) - session->mode = IPSET_LIST_PLAIN; - } else if (cmd == IPSET_CMD_SAVE) { - if (session->mode == IPSET_LIST_NONE) - session->mode = IPSET_LIST_SAVE; - } - - D("next: build_msg"); - /* Build new message or append buffered commands */ - ret = build_msg(session, aggregate); - D("build_msg returned %u", ret); - if (ret > 0) { - /* Buffer is full, send buffered commands */ - ret = ipset_commit(session); - if (ret < 0) - goto cleanup; - ret = build_msg(session, false); - D("build_msg 2 returned %u", ret); - } - if (ret < 0) - goto cleanup; - D("past: build_msg"); - - /* We have to save the type for error handling */ - session->saved_type = ipset_data_get(data, IPSET_OPT_TYPE); - if (session->lineno != 0 && - (cmd == IPSET_CMD_ADD || cmd == IPSET_CMD_DEL)) { - /* Save setname for the next possible aggregated restore line */ - strcpy(session->saved_setname, ipset_data_setname(data)); - ipset_data_reset(data); - /* Don't commit: we may aggregate next command */ - ret = 0; - goto cleanup; - } - - D("call commit"); - ret = ipset_commit(session); - -cleanup: - D("reset data"); - ipset_data_reset(data); - return ret; -} - -/** - * ipset_session_init - initialize an ipset session - * - * Initialize an ipset session by allocating a session structure - * and filling out with the initialization data. - * - * Returns the created session sctructure on success or NULL. - */ -struct ipset_session * -ipset_session_init(ipset_outfn outfn) -{ - struct ipset_session *session; - size_t bufsize = getpagesize(); - - /* Create session object */ - session = calloc(1, sizeof(struct ipset_session) + bufsize); - if (session == NULL) - return NULL; - session->bufsize = bufsize; - session->buffer = session + 1; - - /* The single transport method yet */ - session->transport = &ipset_mnl_transport; - - /* Output function */ - session->outfn = outfn; - - /* Initialize data structures */ - session->data = ipset_data_init(); - if (session->data == NULL) - goto free_session; - - ipset_cache_init(); - return session; - -free_session: - free(session); - return NULL; -} - -/** - * ipset_session_fini - destroy an ipset session - * @session: session structure - * - * Destroy an ipset session: release the created structures. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_session_fini(struct ipset_session *session) -{ - assert(session); - - if (session->handle) - session->transport->fini(session->handle); - if (session->data) - ipset_data_fini(session->data); - - ipset_cache_fini(); - free(session); - return 0; -} - -#ifdef IPSET_DEBUG -#include "debug.c" -#endif diff --git a/extensions/ipset-6/libipset/types.c b/extensions/ipset-6/libipset/types.c deleted file mode 100644 index e93b4bd..0000000 --- a/extensions/ipset-6/libipset/types.c +++ /dev/null @@ -1,556 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* assert */ -#include /* errno */ -#include /* ETH_ALEN */ -#include /* struct in6_addr */ -#include /* AF_ */ -#include /* malloc, free */ -#include /* FIXME: debug */ -#include /* MNL_ALIGN */ - -#include /* D() */ -#include /* ipset_data_* */ -#include /* ipset_cmd */ -#include /* STREQ */ -#include /* prototypes */ - -/* Userspace cache of sets which exists in the kernel */ - -struct ipset { - char name[IPSET_MAXNAMELEN]; /* set name */ - const struct ipset_type *type; /* set type */ - uint8_t family; /* family */ - struct ipset *next; -}; - -static struct ipset_type *typelist; /* registered set types */ -static struct ipset *setlist; /* cached sets */ - -/** - * ipset_cache_add - add a set to the cache - * @name: set name - * @type: set type structure - * - * Add the named set to the internal cache with the specified - * set type. The set name must be unique. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_cache_add(const char *name, const struct ipset_type *type, - uint8_t family) -{ - struct ipset *s, *n; - - assert(name); - assert(type); - - n = malloc(sizeof(*n)); - if (n == NULL) - return -ENOMEM; - - ipset_strlcpy(n->name, name, IPSET_MAXNAMELEN); - n->type = type; - n->family = family; - n->next = NULL; - - if (setlist == NULL) { - setlist = n; - return 0; - } - for (s = setlist; s->next != NULL; s = s->next) { - if (STREQ(name, s->name)) { - free(n); - return -EEXIST; - } - } - s->next = n; - - return 0; -} - -/** - * ipset_cache_del - delete set from the cache - * @name: set name - * - * Delete the named set from the internal cache. If NULL is - * specified as setname, the whole cache is emptied. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_cache_del(const char *name) -{ - struct ipset *s, *match = NULL, *prev = NULL; - - if (!name) { - for (s = setlist; s != NULL; ) { - prev = s; - s = s->next; - free(prev); - } - setlist = NULL; - return 0; - } - for (s = setlist; s != NULL && match == NULL; s = s->next) { - if (STREQ(s->name, name)) { - match = s; - if (prev == NULL) - setlist = match->next; - else - prev->next = match->next; - } - prev = s; - } - if (match == NULL) - return -EEXIST; - - free(match); - return 0; -} - -/** - * ipset_cache_rename - rename a set in the cache - * @from: the set to rename - * @to: the new name of the set - * - * Rename the given set in the cache. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_cache_rename(const char *from, const char *to) -{ - struct ipset *s; - - assert(from); - assert(to); - - for (s = setlist; s != NULL; s = s->next) { - if (STREQ(s->name, from)) { - ipset_strlcpy(s->name, to, IPSET_MAXNAMELEN); - return 0; - } - } - return -EEXIST; -} - -/** - * ipset_cache_swap - swap two sets in the cache - * @from: the first set - * @to: the second set - * - * Swap two existing sets in the cache. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_cache_swap(const char *from, const char *to) -{ - struct ipset *s, *a = NULL, *b = NULL; - - assert(from); - assert(to); - - for (s = setlist; s != NULL && (a == NULL || b == NULL); s = s->next) { - if (a == NULL && STREQ(s->name, from)) - a = s; - if (b == NULL && STREQ(s->name, to)) - b = s; - } - if (a != NULL && b != NULL) { - ipset_strlcpy(a->name, to, IPSET_MAXNAMELEN); - ipset_strlcpy(b->name, from, IPSET_MAXNAMELEN); - return 0; - } - - return -EEXIST; -} - -#define MATCH_FAMILY(type, f) \ - (f == NFPROTO_UNSPEC || type->family == f || \ - type->family == NFPROTO_IPSET_IPV46) - -bool -ipset_match_typename(const char *name, const struct ipset_type *type) -{ - const char * const *alias = type->alias; - - if (STREQ(name, type->name)) - return true; - - while (alias[0]) { - if (STREQ(name, alias[0])) - return true; - alias++; - } - return false; -} - -static inline const struct ipset_type * -create_type_get(struct ipset_session *session) -{ - struct ipset_type *t, *match = NULL; - struct ipset_data *data; - const char *typename; - uint8_t family, tmin = 0, tmax = 0; - uint8_t kmin, kmax; - int ret; - - data = ipset_session_data(session); - assert(data); - typename = ipset_data_get(data, IPSET_OPT_TYPENAME); - assert(typename); - family = ipset_data_family(data); - - /* Check registered types in userspace */ - for (t = typelist; t != NULL; t = t->next) { - /* Skip revisions which are unsupported by the kernel */ - if (t->kernel_check == IPSET_KERNEL_MISMATCH) - continue; - if (ipset_match_typename(typename, t) - && MATCH_FAMILY(t, family)) { - if (match == NULL) { - match = t; - tmin = tmax = t->revision; - } else if (t->family == match->family) - tmin = t->revision; - } - } - if (!match) - return ipset_errptr(session, - "Syntax error: unknown settype %s", - typename); - - /* Family is unspecified yet: set from matching set type */ - if (family == NFPROTO_UNSPEC && match->family != NFPROTO_UNSPEC) { - family = match->family == NFPROTO_IPSET_IPV46 ? - NFPROTO_IPV4 : match->family; - ipset_data_set(data, IPSET_OPT_FAMILY, &family); - } - - if (match->kernel_check == IPSET_KERNEL_OK) - goto found; - - /* Check kernel */ - ret = ipset_cmd(session, IPSET_CMD_TYPE, 0); - if (ret != 0) - return NULL; - - kmin = kmax = *(const uint8_t *)ipset_data_get(data, - IPSET_OPT_REVISION); - if (ipset_data_test(data, IPSET_OPT_REVISION_MIN)) - kmin = *(const uint8_t *)ipset_data_get(data, - IPSET_OPT_REVISION_MIN); - - if (MAX(tmin, kmin) > MIN(tmax, kmax)) { - if (kmin > tmax) - return ipset_errptr(session, - "Kernel supports %s type, family %s " - "with minimal revision %u while ipset program " - "with maximal revision %u.\n" - "You need to upgrade your ipset program.", - typename, - family == NFPROTO_IPV4 ? "INET" : - family == NFPROTO_IPV6 ? "INET6" : "UNSPEC", - kmin, tmax); - else - return ipset_errptr(session, - "Kernel supports %s type, family %s " - "with maximal revision %u while ipset program " - "with minimal revision %u.\n" - "You need to upgrade your kernel.", - typename, - family == NFPROTO_IPV4 ? "INET" : - family == NFPROTO_IPV6 ? "INET6" : "UNSPEC", - kmax, tmin); - } - - /* Disable unsupported revisions */ - for (match = NULL, t = typelist; t != NULL; t = t->next) { - /* Skip revisions which are unsupported by the kernel */ - if (t->kernel_check == IPSET_KERNEL_MISMATCH) - continue; - if (ipset_match_typename(typename, t) - && MATCH_FAMILY(t, family)) { - if (t->revision < kmin || t->revision > kmax) - t->kernel_check = IPSET_KERNEL_MISMATCH; - else if (match == NULL) - match = t; - } - } - match->kernel_check = IPSET_KERNEL_OK; -found: - ipset_data_set(data, IPSET_OPT_TYPE, match); - - return match; -} - -#define set_family_and_type(data, match, family) do { \ - if (family == NFPROTO_UNSPEC && match->family != NFPROTO_UNSPEC) \ - family = match->family == NFPROTO_IPSET_IPV46 ? \ - NFPROTO_IPV4 : match->family;\ - ipset_data_set(data, IPSET_OPT_FAMILY, &family); \ - ipset_data_set(data, IPSET_OPT_TYPE, match); \ -} while (0) - - -static inline const struct ipset_type * -adt_type_get(struct ipset_session *session) -{ - struct ipset_data *data; - struct ipset *s; - struct ipset_type *t; - const struct ipset_type *match; - const char *setname, *typename; - const uint8_t *revision; - uint8_t family = NFPROTO_UNSPEC; - int ret; - - data = ipset_session_data(session); - assert(data); - setname = ipset_data_setname(data); - assert(setname); - - /* Check existing sets in cache */ - for (s = setlist; s != NULL; s = s->next) { - if (STREQ(setname, s->name)) { - ipset_data_set(data, IPSET_OPT_FAMILY, &s->family); - ipset_data_set(data, IPSET_OPT_TYPE, s->type); - return s->type; - } - } - - /* Check kernel */ - ret = ipset_cmd(session, IPSET_CMD_HEADER, 0); - if (ret != 0) - return NULL; - - typename = ipset_data_get(data, IPSET_OPT_TYPENAME); - revision = ipset_data_get(data, IPSET_OPT_REVISION); - family = ipset_data_family(data); - - /* Check registered types */ - for (t = typelist, match = NULL; - t != NULL && match == NULL; t = t->next) { - if (t->kernel_check == IPSET_KERNEL_MISMATCH) - continue; - if (STREQ(typename, t->name) - && MATCH_FAMILY(t, family) - && *revision == t->revision) { - t->kernel_check = IPSET_KERNEL_OK; - match = t; - } - } - if (!match) - return ipset_errptr(session, - "Kernel-library incompatibility: " - "set %s in kernel has got settype %s " - "with family %s and revision %u while " - "ipset library does not support the " - "settype with that family and revision.", - setname, typename, - family == NFPROTO_IPV4 ? "inet" : - family == NFPROTO_IPV6 ? "inet6" : "unspec", - *revision); - - set_family_and_type(data, match, family); - - return match; -} - -/** - * ipset_type_get - get a set type from the kernel - * @session: session structure - * @cmd: the command which needs the set type - * - * Build up and send a private message to the kernel in order to - * get the set type. When creating the set, we send the typename - * and family and get the supported revisions of the given set type. - * When adding/deleting/testing an entry, we send the setname and - * receive the typename, family and revision. - * - * Returns the set type for success and NULL for failure. - */ -const struct ipset_type * -ipset_type_get(struct ipset_session *session, enum ipset_cmd cmd) -{ - assert(session); - - switch (cmd) { - case IPSET_CMD_CREATE: - return create_type_get(session); - case IPSET_CMD_ADD: - case IPSET_CMD_DEL: - case IPSET_CMD_TEST: - return adt_type_get(session); - default: - break; - } - - assert(cmd == IPSET_CMD_NONE); - return NULL; -} - -/** - * ipset_type_check - check the set type received from kernel - * @session: session structure - * - * Check the set type received from the kernel (typename, revision, - * family) against the userspace types looking for a matching type. - * - * Returns the set type for success and NULL for failure. - */ -const struct ipset_type * -ipset_type_check(struct ipset_session *session) -{ - const struct ipset_type *t, *match = NULL; - struct ipset_data *data; - const char *typename; - uint8_t family = NFPROTO_UNSPEC, revision; - - assert(session); - data = ipset_session_data(session); - assert(data); - - typename = ipset_data_get(data, IPSET_OPT_TYPENAME); - family = ipset_data_family(data); - revision = *(const uint8_t *) ipset_data_get(data, IPSET_OPT_REVISION); - - /* Check registered types */ - for (t = typelist; t != NULL && match == NULL; t = t->next) { - if (t->kernel_check == IPSET_KERNEL_MISMATCH) - continue; - if (ipset_match_typename(typename, t) - && MATCH_FAMILY(t, family) - && t->revision == revision) - match = t; - } - if (!match) - return ipset_errptr(session, - "Kernel and userspace incompatible: " - "settype %s with revision %u not supported ", - "by userspace.", typename, revision); - - set_family_and_type(data, match, family); - - return match; -} - -/** - * ipset_type_add - add (register) a userspace set type - * @type: pointer to the set type structure - * - * Add the given set type to the type list. The types - * are added sorted, in descending revision number. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_type_add(struct ipset_type *type) -{ - struct ipset_type *t, *prev; - - assert(type); - - if (strlen(type->name) > IPSET_MAXNAMELEN - 1) - return -EINVAL; - - /* Add to the list: higher revision numbers first */ - for (t = typelist, prev = NULL; t != NULL; t = t->next) { - if (STREQ(t->name, type->name)) { - if (t->revision == type->revision) - return -EEXIST; - else if (t->revision < type->revision) { - type->next = t; - if (prev) - prev->next = type; - else - typelist = type; - return 0; - } - } - if (t->next != NULL && STREQ(t->next->name, type->name)) { - if (t->next->revision == type->revision) - return -EEXIST; - else if (t->next->revision < type->revision) { - type->next = t->next; - t->next = type; - return 0; - } - } - prev = t; - } - type->next = typelist; - typelist = type; - return 0; -} - -/** - * ipset_typename_resolve - resolve typename alias - * @str: typename or alias - * - * Check the typenames (and aliases) and return the - * preferred name of the set type. - * - * Returns the name of the matching set type or NULL. - */ -const char * -ipset_typename_resolve(const char *str) -{ - const struct ipset_type *t; - - for (t = typelist; t != NULL; t = t->next) - if (ipset_match_typename(str, t)) - return t->name; - return NULL; -} - -/** - * ipset_types - return the list of the set types - * - * The types can be unchecked with respect of the running kernel. - * Only useful for type specific help. - * - * Returns the list of the set types. - */ -const struct ipset_type * -ipset_types(void) -{ - return typelist; -} - -/** - * ipset_cache_init - initialize set cache - * - * Initialize the set cache in userspace. - * - * Returns 0 on success or a negative error code. - */ -int -ipset_cache_init(void) -{ - return 0; -} - -/** - * ipset_cache_fini - release the set cache - * - * Release the set cache. - */ -void -ipset_cache_fini(void) -{ - struct ipset *set; - - while (setlist) { - set = setlist; - setlist = setlist->next; - free(set); - } -} diff --git a/extensions/ipset-6/pfxlen.c b/extensions/ipset-6/pfxlen.c deleted file mode 100644 index 71034ab..0000000 --- a/extensions/ipset-6/pfxlen.c +++ /dev/null @@ -1,312 +0,0 @@ -#include "pfxlen.h" - -/* - * Prefixlen maps for fast conversions, by Jan Engelhardt. - */ - -#define E(a, b, c, d) \ - {.ip6 = { \ - __constant_htonl(a), __constant_htonl(b), \ - __constant_htonl(c), __constant_htonl(d), \ - } } - -/* - * This table works for both IPv4 and IPv6; - * just use prefixlen_netmask_map[prefixlength].ip. - */ -const union nf_inet_addr ip_set_netmask_map[] = { - E(0x00000000, 0x00000000, 0x00000000, 0x00000000), - E(0x80000000, 0x00000000, 0x00000000, 0x00000000), - E(0xC0000000, 0x00000000, 0x00000000, 0x00000000), - E(0xE0000000, 0x00000000, 0x00000000, 0x00000000), - E(0xF0000000, 0x00000000, 0x00000000, 0x00000000), - E(0xF8000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFC000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFE000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFF000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFF800000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFC00000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFE00000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFF00000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFF80000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFC0000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFE0000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFF0000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFF8000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFC000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFE000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFF000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFF800, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFC00, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFE00, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFF00, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFF80, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFC0, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFE0, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFF0, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFF8, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFC, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFE, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0x80000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xC0000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xE0000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xF0000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xF8000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFC000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFE000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFF800000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFC00000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFE00000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFF00000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFF80000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFC0000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFE0000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFF0000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFF8000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFC000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFE000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFF000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFF800, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFC00, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFE00, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFF00, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFF80, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFC0, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFE0, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFF0, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFF8, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFC, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFE, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0x80000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xC0000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xE0000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xF0000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xF8000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFC000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFE000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFF800000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFC00000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFE00000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFF00000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFF80000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFC0000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFE0000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF8000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFC000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF800, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFC00, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFE00, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF80, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFC0, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFE0, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF0, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF8, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFC, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xC0000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xE0000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF0000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF8000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFC000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFE000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF800000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFC00000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFE00000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFF00000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFF80000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFC0000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFE0000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF8000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFC000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF800), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFC00), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFE00), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF80), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFC0), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFE0), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF0), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF8), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFC), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF), -}; -EXPORT_SYMBOL_GPL(ip_set_netmask_map); - -#undef E -#define E(a, b, c, d) \ - {.ip6 = { (__force __be32) a, (__force __be32) b, \ - (__force __be32) c, (__force __be32) d, \ - } } - -/* - * This table works for both IPv4 and IPv6; - * just use prefixlen_hostmask_map[prefixlength].ip. - */ -const union nf_inet_addr ip_set_hostmask_map[] = { - E(0x00000000, 0x00000000, 0x00000000, 0x00000000), - E(0x80000000, 0x00000000, 0x00000000, 0x00000000), - E(0xC0000000, 0x00000000, 0x00000000, 0x00000000), - E(0xE0000000, 0x00000000, 0x00000000, 0x00000000), - E(0xF0000000, 0x00000000, 0x00000000, 0x00000000), - E(0xF8000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFC000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFE000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFF000000, 0x00000000, 0x00000000, 0x00000000), - E(0xFF800000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFC00000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFE00000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFF00000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFF80000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFC0000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFE0000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFF0000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFF8000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFC000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFE000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFF000, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFF800, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFC00, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFE00, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFF00, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFF80, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFC0, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFE0, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFF0, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFF8, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFC, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFE, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0x80000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xC0000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xE0000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xF0000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xF8000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFC000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFE000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFF000000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFF800000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFC00000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFE00000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFF00000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFF80000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFC0000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFE0000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFF0000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFF8000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFC000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFE000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFF000, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFF800, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFC00, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFE00, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFF00, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFF80, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFC0, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFE0, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFF0, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFF8, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFC, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFE, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0x80000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xC0000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xE0000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xF0000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xF8000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFC000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFE000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFF800000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFC00000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFE00000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFF00000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFF80000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFC0000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFE0000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF8000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFC000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF000, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF800, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFC00, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFE00, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF80, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFC0, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFE0, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF0, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF8, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFC, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x80000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xC0000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xE0000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF0000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF8000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFC000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFE000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF000000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF800000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFC00000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFE00000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFF00000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFF80000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFC0000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFE0000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF8000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFC000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF000), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF800), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFC00), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFE00), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF80), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFC0), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFE0), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF0), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFF8), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFC), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE), - E(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF), -}; -EXPORT_SYMBOL_GPL(ip_set_hostmask_map); - -/* Find the largest network which matches the range from left, in host order. */ -u32 -ip_set_range_to_cidr(u32 from, u32 to, u8 *cidr) -{ - u32 last; - u8 i; - - for (i = 1; i < 32; i++) { - if ((from & ip_set_hostmask(i)) != from) - continue; - last = from | ~ip_set_hostmask(i); - if (!after(last, to)) { - *cidr = i; - return last; - } - } - *cidr = 32; - return from; -} -EXPORT_SYMBOL_GPL(ip_set_range_to_cidr); diff --git a/extensions/ipset-6/pfxlen.h b/extensions/ipset-6/pfxlen.h deleted file mode 100644 index 199fd11..0000000 --- a/extensions/ipset-6/pfxlen.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _PFXLEN_H -#define _PFXLEN_H - -#include -#include -#include - -/* Prefixlen maps, by Jan Engelhardt */ -extern const union nf_inet_addr ip_set_netmask_map[]; -extern const union nf_inet_addr ip_set_hostmask_map[]; - -static inline __be32 -ip_set_netmask(u8 pfxlen) -{ - return ip_set_netmask_map[pfxlen].ip; -} - -static inline const __be32 * -ip_set_netmask6(u8 pfxlen) -{ - return &ip_set_netmask_map[pfxlen].ip6[0]; -} - -static inline u32 -ip_set_hostmask(u8 pfxlen) -{ - return (__force u32) ip_set_hostmask_map[pfxlen].ip; -} - -static inline const __be32 * -ip_set_hostmask6(u8 pfxlen) -{ - return &ip_set_hostmask_map[pfxlen].ip6[0]; -} - -extern u32 ip_set_range_to_cidr(u32 from, u32 to, u8 *cidr); - -#define ip_set_mask_from_to(from, to, cidr) \ -do { \ - from &= ip_set_hostmask(cidr); \ - to = from | ~ip_set_hostmask(cidr); \ -} while (0) - -#endif /*_PFXLEN_H */ diff --git a/extensions/ipset-6/src/ipset.8 b/extensions/ipset-6/src/ipset.8 deleted file mode 100644 index 37b31eb..0000000 --- a/extensions/ipset-6/src/ipset.8 +++ /dev/null @@ -1,857 +0,0 @@ -.\" Man page written by Jozsef Kadlecsik -.\" -.\" This program is free software; you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 2 of the License, or -.\" (at your option) any later version. -.\" -.\" This program is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this program; if not, write to the Free Software -.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -.TH "IPSET" "8" "Oct 15, 2010" "Jozsef Kadlecsik" "" -.SH "NAME" -ipset \(em administration tool for IP sets -.SH "SYNOPSIS" -\fBipset\fR [ \fIOPTIONS\fR ] \fICOMMAND\fR [ \fICOMMAND\-OPTIONS\fR ] -.PP -COMMANDS := { \fBcreate\fR | \fBadd\fR | \fBdel\fR | \fBtest\fR | \fBdestroy\fR | \fBlist\fR | \fBsave\fR | \fBrestore\fR | \fBflush\fR | \fBrename\fR | \fBswap\fR | \fBhelp\fR | \fBversion\fR | \fB\-\fR } -.PP -\fIOPTIONS\fR := { \fB\-exist\fR | \fB\-output\fR { \fBplain\fR | \fBsave\fR | \fBxml\fR } | \fB\-quiet\fR | \fB\-resolve\fR | \fB\-sorted\fR | \fB\-name\fR | \fB\-terse\fR } -.PP -\fBipset\fR \fBcreate\fR \fISETNAME\fR \fITYPENAME\fR [ \fICREATE\-OPTIONS\fR ] -.PP -\fBipset\fR \fBadd\fR \fISETNAME\fR \fIADD\-ENTRY\fR [ \fIADD\-OPTIONS\fR ] -.PP -\fBipset\fR \fBdel\fR \fISETNAME\fR \fIDEL\-ENTRY\fR [ \fIDEL\-OPTIONS\fR ] -.PP -\fBipset\fR \fBtest\fR \fISETNAME\fR \fITEST\-ENTRY\fR [ \fITEST\-OPTIONS\fR ] -.PP -\fBipset\fR \fBdestroy\fR [ \fISETNAME\fR ] -.PP -\fBipset\fR \fBlist\fR [ \fISETNAME\fR ] -.PP -\fBipset\fR \fBsave\fR [ \fISETNAME\fR ] -.PP -\fBipset\fR \fBrestore\fR -.PP -\fBipset\fR \fBflush\fR [ \fISETNAME\fR ] -.PP -\fBipset\fR \fBrename\fR \fISETNAME\-FROM\fR \fISETNAME\-TO\fR -.PP -\fBipset\fR \fBswap\fR \fISETNAME\-FROM\fR \fISETNAME\-TO\fR -.PP -\fBipset\fR \fBhelp\fR [ \fITYPENAME\fR ] -.PP -\fBipset\fR \fBversion\fR -.PP -\fBipset\fR \fB\-\fR -.SH "DESCRIPTION" -\fBipset\fR -is used to set up, maintain and inspect so called IP sets in the Linux -kernel. Depending on the type of the set, an IP set may store IP(v4/v6) -addresses, (TCP/UDP) port numbers, IP and MAC address pairs, IP address -and port number pairs, etc. See the set type definitions below. -.PP -\fBIptables\fR -matches and targets referring to sets create references, which -protect the given sets in the kernel. A set cannot be destroyed -while there is a single reference pointing to it. -.SH "OPTIONS" -The options that are recognized by -\fBipset\fR -can be divided into several different groups. -.SS COMMANDS -These options specify the desired action to perform. Only one of them -can be specified on the command line unless otherwise specified below. -For all the long versions of the command names, you need to use only enough -letters to ensure that -\fBipset\fR -can differentiate it from all other commands. The -\fBipset\fR -parser follows the order here when looking for the shortest match -in the long command names. -.TP -\fBn\fP, \fBcreate\fP \fISETNAME\fP \fITYPENAME\fP [ \fICREATE\-OPTIONS\fP ] -Create a set identified with setname and specified type. The type may require -type specific options. If the -\fB\-exist\fR -option is specified, -\fBipset\fR -ignores the error otherwise raised when the same set (setname and create parameters -are identical) already exists. -.TP -\fBadd\fP \fISETNAME\fP \fIADD\-ENTRY\fP [ \fIADD\-OPTIONS\fP ] -Add a given entry to the set. If the -\fB\-exist\fR -option is specified, -\fBipset\fR -ignores if the entry already added to the set. -.TP -\fBdel\fP \fISETNAME\fP \fIDEL\-ENTRY\fP [ \fIDEL\-OPTIONS\fP ] -Delete an entry from a set. If the -\fB\-exist\fR -option is specified, -\fBipset\fR -ignores if the entry does not added to (already expired from) the set. -.TP -\fBtest\fP \fISETNAME\fP \fITEST\-ENTRY\fP [ \fITEST\-OPTIONS\fP ] -Test wether an entry is in a set or not. Exit status number is zero -if the tested entry is in the set and nonzero if it is missing from -the set. -.TP -\fBx\fP, \fBdestroy\fP [ \fISETNAME\fP ] -Destroy the specified set or all the sets if none is given. - -If the set has got reference(s), nothing is done and no set destroyed. -.TP -\fBlist\fP [ \fISETNAME\fP ] [ \fIOPTIONS\fP ] -List the header data and the entries for the specified set, or for -all sets if none is given. The -\fB\-resolve\fP -option can be used to force name lookups (which may be slow). When the -\fB\-sorted\fP -option is given, the entries are listed sorted (if the given set -type supports the operation). The option -\fB\-output\fR -can be used to control the format of the listing: -\fBplain\fR, \fBsave\fR or \fBxml\fR. -(The default is -\fBplain\fR.) -If the option -\fB\-name\fR -is specified, just the names of the existing sets are listed. If the option -\fB\-terse\fR -is specified, just the set names and headers are listed. -.TP -\fBsave\fP [ \fISETNAME\fP ] -Save the given set, or all sets if none is given -to stdout in a format that -\fBrestore\fP -can read. -.TP -\fBrestore\fP -Restore a saved session generated by -\fBsave\fP. -The saved session can be fed from stdin. -.TP -\fBflush\fP [ \fISETNAME\fP ] -Flush all entries from the specified set or flush -all sets if none is given. -.TP -\fBe\fP, \fBrename\fP \fISETNAME\-FROM\fP \fISETNAME\-TO\fP -Rename a set. Set identified by -\fISETNAME\-TO\fR -must not exist. -.TP -\fBw\fP, \fBswap\fP \fISETNAME\-FROM\fP \fISETNAME\-TO\fP -Swap the content of two sets, or in another words, -exchange the name of two sets. The referred sets must exist and -identical type of sets can be swapped only. -.TP -\fBhelp\fP [ \fITYPENAME\fP ] -Print help and set type specific help if -\fITYPENAME\fR -is specified. -.TP -\fBversion\fP -Print program version. -.TP -\fB\-\fP -If a dash is specified as command, then -\fBipset\fR -enters a simple interactive mode and the commands are read from the standard input. -The interactive mode can be finished by entering the pseudo\-command -\fBquit\fR. -.P -.SS "OTHER OPTIONS" -The following additional options can be specified. The long option names -cannot be abbreviated. -.TP -\fB\-!\fP, \fB\-exist\fP -Ignore errors when the exactly the same set is to be created or already -added entry is added or missing entry is deleted. -.TP -\fB\-o\fP, \fB\-output\fP { \fBplain\fR | \fBsave\fR | \fBxml\fR } -Select the output format to the -\fBlist\fR -command. -.TP -\fB\-q\fP, \fB\-quiet\fP -Suppress any output to stdout and stderr. -\fBipset\fR -will still exit with error if it cannot continue. -.TP -\fB\-r\fP, \fB\-resolve\fP -When listing sets, enforce name lookup. The -program will try to display the IP entries resolved to -host names which requires -\fBslow\fR -DNS lookups. -.TP -\fB\-s\fP, \fB\-sorted\fP -Sorted output. When listing sets entries are listed sorted. Not supported yet. -.TP -\fB\-n\fP, \fB\-name\fP -List just the names of the existing sets, i.e. suppress listing of set headers and members. -.TP -\fB\-t\fP, \fB\-terse\fP -List the set names and headers, i.e. suppress listing of set members. - -.SH "SET TYPES" -A set type comprises of the storage method by which the data is stored and -the data type(s) which are stored in the set. Therefore the -\fITYPENAME\fR -parameter of the -\fBcreate\fR -command follows the syntax - -\fITYPENAME\fR := \fImethod\fR\fB:\fR\fIdatatype\fR[\fB,\fR\fIdatatype\fR[\fB,\fR\fIdatatype\fR]] - -where the current list of the methods are -\fBbitmap\fR, \fBhash\fR, and \fBlist\fR and the possible data types -are \fBip\fR, \fBnet\fR, \fBmac\fR, \fBport\fR and \fBiface\fR. -The dimension of a set is equal to the number of data types in its type name. - -When adding, deleting or testing entries in a set, the same comma separated -data syntax must be used for the entry parameter of the commands, i.e - -ipset add foo ipaddr,portnum,ipaddr - -The \fBbitmap\fR and \fBlist\fR types use a fixed sized storage. The \fBhash\fR -types use a hash to store the elements. In order to avoid clashes in the hash, -a limited number of chaining, and if that is exhausted, the doubling of the hash size -is performed when adding entries by the -\fBipset\fR -command. When entries added by the -\fBSET\fR -target of -\fBiptables/ip6tables\fR, -then the hash size is fixed and the set won't be duplicated, even if the new -entry cannot be added to the set. - -All set types support the optional - -\fBtimeout\fR \fIvalue\fR - -parameter when creating a set and adding entries. The value of the \fBtimeout\fR -parameter for the \fBcreate\fR command means the default timeout value (in seconds) -for new entries. If a set is created with timeout support, then the same -\fBtimeout\fR option can be used to specify non\-default timeout values -when adding entries. Zero timeout value means the entry is added permanent to the set. -The timeout value of already added elements can be changed by readding the element -using the \fB\-exist\fR option. -.SS bitmap:ip -The \fBbitmap:ip\fR set type uses a memory range to store either IPv4 host -(default) or IPv4 network addresses. A \fBbitmap:ip\fR type of set can store up -to 65536 entries. -.PP -\fICREATE\-OPTIONS\fR := \fBrange\fP \fIfromip\fP\-\fItoip\fR|\fIip\fR/\fIcidr\fR [ \fBnetmask\fP \fIcidr\fP ] [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIADD\-ENTRY\fR := { \fIip\fR | \fIfromip\fR\-\fItoip\fR | \fIip\fR/\fIcidr\fR } -.PP -\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIDEL\-ENTRY\fR := { \fIip\fR | \fIfromip\fR\-\fItoip\fR | \fIip\fR/\fIcidr\fR } -.PP -\fITEST\-ENTRY\fR := \fIip\fR -.PP -Mandatory \fBcreate\fR options: -.TP -\fBrange\fP \fIfromip\fP\-\fItoip\fR|\fIip\fR/\fIcidr\fR -Create the set from the specified inclusive address range expressed in an -IPv4 address range or network. The size of the range (in entries) cannot exceed -the limit of maximum 65536 elements. -.PP -Optional \fBcreate\fR options: -.TP -\fBnetmask\fP \fIcidr\fP -When the optional \fBnetmask\fP parameter specified, network addresses will be -stored in the set instead of IP host addresses. The \fIcidr\fR prefix value must be -between 1\-32. -An IP address will be in the set if the network address, which is resulted by -masking the address with the specified netmask calculated from the prefix, -can be found in the set. -.PP -The \fBbitmap:ip\fR type supports adding or deleting multiple entries in one -command. -.PP -Examples: -.IP -ipset create foo bitmap:ip range 192.168.0.0/16 -.IP -ipset add foo 192.168.1/24 -.IP -ipset test foo 192.168.1.1 -.SS bitmap:ip,mac -The \fBbitmap:ip,mac\fR set type uses a memory range to store IPv4 and a MAC address pairs. A \fBbitmap:ip,mac\fR type of set can store up to 65536 entries. -.PP -\fICREATE\-OPTIONS\fR := \fBrange\fP \fIfromip\fP\-\fItoip\fR|\fIip\fR/\fIcidr\fR [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIADD\-ENTRY\fR := \fIip\fR[,\fImacaddr\fR] -.PP -\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIDEL\-ENTRY\fR := \fIip\fR[,\fImacaddr\fR] -.PP -\fITEST\-ENTRY\fR := \fIip\fR[,\fImacaddr\fR] -.PP -Mandatory options to use when creating a \fBbitmap:ip,mac\fR type of set: -.TP -\fBrange\fP \fIfromip\fP\-\fItoip\fR|\fIip\fR/\fIcidr\fR -Create the set from the specified inclusive address range expressed in an -IPv4 address range or network. The size of the range cannot exceed the limit -of maximum 65536 entries. -.PP -The \fBbitmap:ip,mac\fR type is exceptional in the sense that the MAC part can -be left out when adding/deleting/testing entries in the set. If we add an entry -without the MAC address specified, then when the first time the entry is -matched by the kernel, it will automatically fill out the missing MAC address with the -source MAC address from the packet. If the entry was specified with a timeout value, -the timer starts off when the IP and MAC address pair is complete. -.PP -The \fBbitmap:ip,mac\fR type of sets require two \fBsrc/dst\fR parameters of -the \fBset\fR match and \fBSET\fR target netfilter kernel modules and the second -one must be \fBsrc\fR to match, add or delete entries because the \fBset\fR match -and \fBSET\fR target have access to the source MAC address only. -.PP -Examples: -.IP -ipset create foo bitmap:ip,mac range 192.168.0.0/16 -.IP -ipset add foo 192.168.1.1,12:34:56:78:9A:BC -.IP -ipset test foo 192.168.1.1 -.SS bitmap:port -The \fBbitmap:port\fR set type uses a memory range to store port numbers -and such a set can store up to 65536 ports. -.PP -\fICREATE\-OPTIONS\fR := \fBrange\fP \fIfromport\fP\-\fItoport [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIADD\-ENTRY\fR := { \fIport\fR | \fIfromport\fR\-\fItoport\fR } -.PP -\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIDEL\-ENTRY\fR := { \fIport\fR | \fIfromport\fR\-\fItoport\fR } -.PP -\fITEST\-ENTRY\fR := \fIport\fR -.PP -Mandatory options to use when creating a \fBbitmap:port\fR type of set: -.TP -\fBrange\fP \fIfromport\fP\-\fItoport\fR -Create the set from the specified inclusive port range. -.PP -The \fBset\fR match and \fBSET\fR target netfilter kernel modules interpret -the stored numbers as TCP or UDP port numbers. -.PP -Examples: -.IP -ipset create foo bitmap:port range 0\-1024 -.IP -ipset add foo 80 -.IP -ipset test foo 80 -.SS hash:ip -The \fBhash:ip\fR set type uses a hash to store IP host addresses (default) or -network addresses. Zero valued IP address cannot be stored in a \fBhash:ip\fR -type of set. -.PP -\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBnetmask\fP \fIcidr\fP ] [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIADD\-ENTRY\fR := \fIipaddr\fR -.PP -\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIDEL\-ENTRY\fR := \fIipaddr\fR -.PP -\fITEST\-ENTRY\fR := \fIipaddr\fR -.PP -Optional \fBcreate\fR options: -.TP -\fBfamily\fR { \fBinet\fR | \fBinet6\fR } -The protocol family of the IP addresses to be stored in the set. The default is -\fBinet\fR, i.e IPv4. -.TP -\fBhashsize\fR \fIvalue\fR -The initial hash size for the set, default is 1024. The hash size must be a power -of two, the kernel automatically rounds up non power of two hash sizes to the first -correct value. -.TP -\fBmaxelem\fR \fIvalue\fR -The maximal number of elements which can be stored in the set, default 65536. -.TP -\fBnetmask\fP \fIcidr\fP -When the optional \fBnetmask\fP parameter specified, network addresses will be -stored in the set instead of IP host addresses. The \fIcidr\fP prefix value must be -between 1\-32 for IPv4 and between 1\-128 for IPv6. An IP address will be in the set -if the network address, which is resulted by masking the address with the netmask -calculated from the prefix, can be found in the set. -.PP -For the \fBinet\fR family one can add or delete multiple entries by specifying -a range or a network: -.PP -\fIipaddr\fR := { \fIip\fR | \fIfromaddr\fR\-\fItoaddr\fR | \fIip\fR/\fIcidr\fR } -.PP -Examples: -.IP -ipset create foo hash:ip netmask 30 -.IP -ipset add foo 192.168.1.0/24 -.IP -ipset test foo 192.168.1.2 -.SS hash:net -The \fBhash:net\fR set type uses a hash to store different sized IP network addresses. -Network address with zero prefix size cannot be stored in this type of sets. -.PP -\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIADD\-ENTRY\fR := \fInetaddr\fR -.PP -\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIDEL\-ENTRY\fR := \fInetaddr\fR -.PP -\fITEST\-ENTRY\fR := \fInetaddr\fR -.PP -where -\fInetaddr\fR := \fIip\fR[/\fIcidr\fR] -.PP -Optional \fBcreate\fR options: -.TP -\fBfamily\fR { \fBinet\fR | \fBinet6\fR } -The protocol family of the IP addresses to be stored in the set. The default is -\fBinet\fR, i.e IPv4. -.TP -\fBhashsize\fR \fIvalue\fR -The initial hash size for the set, default is 1024. The hash size must be a power -of two, the kernel automatically rounds up non power of two hash sizes to the first -correct value. -.TP -\fBmaxelem\fR \fIvalue\fR -The maximal number of elements which can be stored in the set, default 65536. -.PP -For the \fBinet\fR family one can add or delete multiple entries by specifying -a range, which is converted internally to network(s) equal to the range: -.PP -\fInetaddr\fR := { \fIip\fR[/\fIcidr\fR] | \fIfromaddr\fR\-\fItoaddr\fR } -.PP -When adding/deleting/testing entries, if the cidr prefix parameter is not specified, -then the host prefix value is assumed. When adding/deleting entries, the exact -element is added/deleted and overlapping elements are not checked by the kernel. -When testing entries, if a host address is tested, then the kernel tries to match -the host address in the networks added to the set and reports the result accordingly. -.PP -From the \fBset\fR netfilter match point of view the searching for a match -always starts from the smallest size of netblock (most specific -prefix) to the largest one (least specific prefix) added to the set. -When adding/deleting IP addresses to the set by the \fBSET\fR netfilter target, -it will be added/deleted by the most specific prefix which can be found in the -set, or by the host prefix value if the set is empty. -.PP -The lookup time grows linearly with the number of the different prefix -values added to the set. -.PP -Examples: -.IP -ipset create foo hash:net -.IP -ipset add foo 192.168.0.0/24 -.IP -ipset add foo 10.1.0.0/16 -.IP -ipset test foo 192.168.0/24 -.SS hash:ip,port -The \fBhash:ip,port\fR set type uses a hash to store IP address and port number pairs. -The port number is interpreted together with a protocol (default TCP) and zero -protocol number cannot be used. -.PP -\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIADD\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR -.PP -\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIDEL\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR -.PP -\fITEST\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR -.PP -Optional \fBcreate\fR options: -.TP -\fBfamily\fR { \fBinet\fR | \fBinet6\fR } -The protocol family of the IP addresses to be stored in the set. The default is -\fBinet\fR, i.e IPv4. -.TP -\fBhashsize\fR \fIvalue\fR -The initial hash size for the set, default is 1024. The hash size must be a power -of two, the kernel automatically rounds up non power of two hash sizes to the first -correct value -.TP -\fBmaxelem\fR \fIvalue\fR -The maximal number of elements which can be stored in the set, default 65536. -.PP -For the \fBinet\fR family one can add or delete multiple entries by specifying -a range or a network of IPv4 addresses in the IP address part of the entry: -.PP -\fIipaddr\fR := { \fIip\fR | \fIfromaddr\fR\-\fItoaddr\fR | \fIip\fR/\fIcidr\fR } -.PP -The -[\fIproto\fR:]\fIport\fR -part of the elements may be expressed in the following forms, where the range -variations are valid when adding or deleting entries: -.TP -\fIportname[\-portname]\fR -TCP port or range of ports expressed in TCP portname identifiers from /etc/services -.TP -\fIportnumber[\-portnumber]\fR -TCP port or range of ports expressed in TCP port numbers -.TP -\fBtcp\fR|\fBsctp\fR|\fBudp\fR|\fBudplite\fR:\fIportname\fR|\fIportnumber\fR[\-\fIportname\fR|\fIportnumber\fR] -TCP, SCTP, UDP or UDPLITE port or port range expressed in port name(s) or port number(s) -.TP -\fBicmp\fR:\fIcodename\fR|\fItype\fR/\fIcode\fR -ICMP codename or type/code. The supported ICMP codename identifiers can always -be listed by the help command. -.TP -\fBicmpv6\fR:\fIcodename\fR|\fItype\fR/\fIcode\fR -ICMPv6 codename or type/code. The supported ICMPv6 codename identifiers can always -be listed by the help command. -.TP -\fIproto\fR:0 -All other protocols, as an identifier from /etc/protocols or number. The pseudo -port number must be zero. -.PP -The \fBhash:ip,port\fR type of sets require -two \fBsrc\fR/\fBdst\fR parameters of the \fBset\fR match and \fBSET\fR -target kernel modules. -.PP -Examples: -.IP -ipset create foo hash:ip,port -.IP -ipset add foo 192.168.1.0/24,80\-82 -.IP -ipset add foo 192.168.1.1,udp:53 -.IP -ipset add foo 192.168.1.1,vrrp:0 -.IP -ipset test foo 192.168.1.1,80 -.SS hash:net,port -The \fBhash:net,port\fR set type uses a hash to store different sized IP network -address and port pairs. The port number is interpreted together with a protocol -(default TCP) and zero protocol number cannot be used. Network -address with zero prefix size is not accepted either. -.PP -\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIADD\-ENTRY\fR := \fInetaddr\fR,[\fIproto\fR:]\fIport\fR -.PP -\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIDEL\-ENTRY\fR := \fInetaddr\fR,[\fIproto\fR:]\fIport\fR -.PP -\fITEST\-ENTRY\fR := \fInetaddr\fR,[\fIproto\fR:]\fIport\fR -.PP -where -\fInetaddr\fR := \fIip\fR[/\fIcidr\fR] -.PP -Optional \fBcreate\fR options: -.TP -\fBfamily\fR { \fBinet\fR | \fBinet6\fR } -The protocol family of the IP addresses to be stored in the set. The default is -\fBinet\fR, i.e IPv4. -.TP -\fBhashsize\fR \fIvalue\fR -The initial hash size for the set, default is 1024. The hash size must be a power -of two, the kernel automatically rounds up non power of two hash sizes to the first -correct value. -.TP -\fBmaxelem\fR \fIvalue\fR -The maximal number of elements which can be stored in the set, default 65536. -.PP -For the \fInetaddr\fR part of the elements -see the description at the \fBhash:net\fR set type. For the -[\fIproto\fR:]\fIport\fR -part of the elements see the description at the -\fBhash:ip,port\fR set type. -.PP -When adding/deleting/testing entries, if the cidr prefix parameter is not specified, -then the host prefix value is assumed. When adding/deleting entries, the exact -element is added/deleted and overlapping elements are not checked by the kernel. -When testing entries, if a host address is tested, then the kernel tries to match -the host address in the networks added to the set and reports the result accordingly. -.PP -From the \fBset\fR netfilter match point of view the searching for a match -always starts from the smallest size of netblock (most specific -prefix) to the largest one (least specific prefix) added to the set. -When adding/deleting IP -addresses to the set by the \fBSET\fR netfilter target, it will be -added/deleted by the most specific prefix which can be found in the -set, or by the host prefix value if the set is empty. -.PP -The lookup time grows linearly with the number of the different prefix -values added to the set. -.PP -Examples: -.IP -ipset create foo hash:net,port -.IP -ipset add foo 192.168.0/24,25 -.IP -ipset add foo 10.1.0.0/16,80 -.IP -ipset test foo 192.168.0/24,25 -.SS hash:ip,port,ip -The \fBhash:ip,port,ip\fR set type uses a hash to store IP address, port number -and a second IP address triples. The port number is interpreted together with a -protocol (default TCP) and zero protocol number cannot be used. -.PP -\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIADD\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fIip\fR -.PP -\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIDEL\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fIip\fR -.PP -\fITEST\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fIip\fR -.PP -For the first \fIipaddr\fR and -[\fIproto\fR:]\fIport\fR -parts of the elements see the descriptions at the -\fBhash:ip,port\fR set type. -.PP -Optional \fBcreate\fR options: -.TP -\fBfamily\fR { \fBinet\fR | \fBinet6\fR } -The protocol family of the IP addresses to be stored in the set. The default is -\fBinet\fR, i.e IPv4. -.TP -\fBhashsize\fR \fIvalue\fR -The initial hash size for the set, default is 1024. The hash size must be a power -of two, the kernel automatically rounds up non power of two hash sizes to the first -correct value. -.TP -\fBmaxelem\fR \fIvalue\fR -The maximal number of elements which can be stored in the set, default 65536. -.PP -The \fBhash:ip,port,ip\fR type of sets require -three \fBsrc\fR/\fBdst\fR parameters of the \fBset\fR match and \fBSET\fR -target kernel modules. -.PP -Examples: -.IP -ipset create foo hash:ip,port,ip -.IP -ipset add foo 192.168.1.1,80,10.0.0.1 -.IP -ipset test foo 192.168.1.1,udp:53,10.0.0.1 -.SS hash:ip,port,net -The \fBhash:ip,port,net\fR set type uses a hash to store IP address, port number -and IP network address triples. The port number is interpreted together with a -protocol (default TCP) and zero protocol number cannot be used. Network -address with zero prefix size cannot be stored either. -.PP -\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIADD\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fInetaddr\fR -.PP -\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIDEL\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fInetaddr\fR -.PP -\fITEST\-ENTRY\fR := \fIipaddr\fR,[\fIproto\fR:]\fIport\fR,\fInetaddr\fR -.PP -where -\fInetaddr\fR := \fIip\fR[/\fIcidr\fR] -.PP -For the \fIipaddr\fR and -[\fIproto\fR:]\fIport\fR -parts of the elements see the descriptions at the -\fBhash:ip,port\fR set type. For the \fInetaddr\fR part of the elements -see the description at the \fBhash:net\fR set type. -.PP -Optional \fBcreate\fR options: -.TP -\fBfamily\fR { \fBinet\fR | \fBinet6\fR } -The protocol family of the IP addresses to be stored in the set. The default is -\fBinet\fR, i.e IPv4. -.TP -\fBhashsize\fR \fIvalue\fR -The initial hash size for the set, default is 1024. The hash size must be a power -of two, the kernel automatically rounds up non power of two hash sizes to the first -correct value. -.TP -\fBmaxelem\fR \fIvalue\fR -The maximal number of elements which can be stored in the set, default 65536. -.PP -From the \fBset\fR netfilter match point of view the searching for a match -always starts from the smallest size of netblock (most specific -cidr) to the largest one (least specific cidr) added to the set. -When adding/deleting triples -to the set by the \fBSET\fR netfilter target, it will be -added/deleted by the most specific cidr which can be found in the -set, or by the host cidr value if the set is empty. -.PP -The lookup time grows linearly with the number of the different \fIcidr\fR -values added to the set. -.PP -The \fBhash:ip,port,net\fR type of sets require three \fBsrc\fR/\fBdst\fR parameters of -the \fBset\fR match and \fBSET\fR target kernel modules. -.PP -Examples: -.IP -ipset create foo hash:ip,port,net -.IP -ipset add foo 192.168.1,80,10.0.0/24 -.IP -ipset add foo 192.168.2,25,10.1.0.0/16 -.IP -ipset test foo 192.168.1,80.10.0.0/24 -.SS hash:net,iface -The \fBhash:net,iface\fR set type uses a hash to store different sized IP network -address and interface name pairs. Network address with zero prefix size is not -accepted. -.PP -\fICREATE\-OPTIONS\fR := [ \fBfamily\fR { \fBinet\fR | \fBinet6\fR } ] | [ \fBhashsize\fR \fIvalue\fR ] [ \fBmaxelem\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIADD\-ENTRY\fR := \fInetaddr\fR,[\fBphysdev\fR:]\fIiface\fR -.PP -\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIDEL\-ENTRY\fR := \fInetaddr\fR,[\fBphysdev\fR:]\fIiface\fR -.PP -\fITEST\-ENTRY\fR := \fInetaddr\fR,[\fBphysdev\fR:]\fIiface\fR -.PP -where -\fInetaddr\fR := \fIip\fR[/\fIcidr\fR] -.PP -Optional \fBcreate\fR options: -.TP -\fBfamily\fR { \fBinet\fR | \fBinet6\fR } -The protocol family of the IP addresses to be stored in the set. The default is -\fBinet\fR, i.e IPv4. -.TP -\fBhashsize\fR \fIvalue\fR -The initial hash size for the set, default is 1024. The hash size must be a power -of two, the kernel automatically rounds up non power of two hash sizes to the first -correct value. -.TP -\fBmaxelem\fR \fIvalue\fR -The maximal number of elements which can be stored in the set, default 65536. -.PP -For the \fInetaddr\fR part of the elements -see the description at the \fBhash:net\fR set type. -.PP -When adding/deleting/testing entries, if the cidr prefix parameter is not specified, -then the host prefix value is assumed. When adding/deleting entries, the exact -element is added/deleted and overlapping elements are not checked by the kernel. -When testing entries, if a host address is tested, then the kernel tries to match -the host address in the networks added to the set and reports the result accordingly. -.PP -From the \fBset\fR netfilter match point of view the searching for a match -always starts from the smallest size of netblock (most specific -prefix) to the largest one (least specific prefix) added to the set. -When adding/deleting IP -addresses to the set by the \fBSET\fR netfilter target, it will be -added/deleted by the most specific prefix which can be found in the -set, or by the host prefix value if the set is empty. -.PP -The second direction parameter of the \fBset\fR match and -\fBSET\fR target modules corresponds to the incoming/outgoing interface -: \fBsrc\fR to the incoming, while \fBdst\fR to the outgoing. When -the interface is flagged with \fBphysdev:\fR, the interface is interpreted -as the incoming/outgoing bridge port. -.PP -The lookup time grows linearly with the number of the different prefix -values added to the set. -.PP -The internal restriction of the \fBhash:net,iface\fR set type is that -the same network prefix cannot be stored with more than 64 different interfaces -in a single set. -.PP -Examples: -.IP -ipset create foo hash:net,iface -.IP -ipset add foo 192.168.0/24,eth0 -.IP -ipset add foo 10.1.0.0/16,eth1 -.IP -ipset test foo 192.168.0/24,eth0 -.SS list:set -The \fBlist:set\fR type uses a simple list in which you can store -set names. -.PP -\fICREATE\-OPTIONS\fR := [ \fBsize\fR \fIvalue\fR ] [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIADD\-ENTRY\fR := \fIsetname\fR [ { \fBbefore\fR | \fBafter\fR } \fIsetname\fR ] -.PP -\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] -.PP -\fIDEL\-ENTRY\fR := \fIsetname\fR [ { \fBbefore\fR | \fBafter\fR } \fIsetname\fR ] -.PP -\fITEST\-ENTRY\fR := \fIsetname\fR [ { \fBbefore\fR | \fBafter\fR } \fIsetname\fR ] -.PP -Optional \fBcreate\fR options: -.TP -\fBsize\fR \fIvalue\fR -The size of the list, the default is 8. -.PP -By the \fBipset\fR commad you can add, delete and test set names in a -\fBlist:set\fR type of set. -.PP -By the \fBset\fR match or \fBSET\fR target of netfilter -you can test, add or delete entries in the sets added to the \fBlist:set\fR -type of set. The match will try to find a matching entry in the sets and -the target will try to add an entry to the first set to which it can be added. -The number of direction options of the match and target are important: sets which -require more parameters than specified are skipped, while sets with equal -or less parameters are checked, elements added/deleted. For example if \fIa\fR and -\fIb\fR are \fBlist:set\fR type of sets then in the command -.IP -iptables \-m set \-\-match\-set a src,dst \-j SET \-\-add\-set b src,dst -.PP -the match and target will skip any set in \fIa\fR and \fIb\fR -which stores data triples, but will match all sets with single or double -data storage in \fIa\fR set and stop matching at the first successful set, -and add src to the first single or src,dst to the first double data storage set -in \fIb\fR to which the entry can be added. You can imagine a \fBlist:set\fR -type of set as an ordered union of the set elements. -.PP -Please note: by the \fBipset\fR commad you can add, delete and \fBtest\fR -the setnames in a \fBlist:set\fR type of set, and \fBnot\fR the presence of -a set's member (such as an IP address). -.SH "GENERAL RESTRICTIONS" -Zero valued set entries cannot be used with hash methods. Zero protocol value with ports -cannot be used. -.SH "COMMENTS" -If you want to store same size subnets from a given network -(say /24 blocks from a /8 network), use the \fBbitmap:ip\fR set type. -If you want to store random same size networks (say random /24 blocks), -use the \fBhash:ip\fR set type. If you have got random size of netblocks, -use \fBhash:net\fR. -.PP -Backward compatibility is maintained and old \fBipset\fR syntax is still supported. -.PP -The \fBiptree\fR and \fBiptreemap\fR set types are removed: if you refer to them, -they are automatically replaced by \fBhash:ip\fR type of sets. -.SH "DIAGNOSTICS" -Various error messages are printed to standard error. The exit code -is 0 for correct functioning. -.SH "BUGS" -Bugs? No, just funny features. :\-) -OK, just kidding... -.SH "SEE ALSO" -\fBiptables\fR(8), -\fBip6tables\fR(8) -.SH "AUTHORS" -Jozsef Kadlecsik wrote ipset, which is based on ippool by -Joakim Axelsson, Patrick Schaaf and Martin Josefsson. -.br -Sven Wegener wrote the iptreemap type. -.SH "LAST REMARK" -\fBI stand on the shoulders of giants.\fR diff --git a/extensions/ipset-6/src/ipset.c b/extensions/ipset-6/src/ipset.c deleted file mode 100644 index 15d390f..0000000 --- a/extensions/ipset-6/src/ipset.c +++ /dev/null @@ -1,755 +0,0 @@ -/* Copyright 2000-2002 Joakim Axelsson (gozem@linux.nu) - * Patrick Schaaf (bof@bof.de) - * Copyright 2003-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* isspace */ -#include /* va_* */ -#include /* bool */ -#include /* fprintf, fgets */ -#include /* exit */ -#include /* str* */ - -#include - -#include /* D() */ -#include /* enum ipset_data */ -#include /* ipset_parse_* */ -#include /* ipset_session_* */ -#include /* struct ipset_type */ -#include /* core options, commands */ -#include /* STREQ */ - -static char program_name[] = "ipset"; -static char program_version[] = "6.10-genl-xta"; - -static struct ipset_session *session; -static uint32_t restore_line; -static bool interactive; -static char cmdline[1024]; -static char *newargv[255]; -static int newargc; - -/* The known set types: (typename, revision, family) is unique */ -extern struct ipset_type ipset_bitmap_ip0; -extern struct ipset_type ipset_bitmap_ipmac0; -extern struct ipset_type ipset_bitmap_port0; -extern struct ipset_type ipset_hash_ip0; -extern struct ipset_type ipset_hash_net0; -extern struct ipset_type ipset_hash_net1; -extern struct ipset_type ipset_hash_netport1; -extern struct ipset_type ipset_hash_netport2; -extern struct ipset_type ipset_hash_netiface0; -extern struct ipset_type ipset_hash_ipport1; -extern struct ipset_type ipset_hash_ipportip1; -extern struct ipset_type ipset_hash_ipportnet1; -extern struct ipset_type ipset_hash_ipportnet2; -extern struct ipset_type ipset_list_set0; - -enum exittype { - NO_PROBLEM = 0, - OTHER_PROBLEM, - PARAMETER_PROBLEM, - VERSION_PROBLEM, - SESSION_PROBLEM, -}; - -static int __attribute__((format(printf, 2, 3))) -exit_error(int status, const char *msg, ...) -{ - bool quiet = !interactive && - session && - ipset_envopt_test(session, IPSET_ENV_QUIET); - - if (status && msg && !quiet) { - va_list args; - - fprintf(stderr, "%s v%s: ", program_name, program_version); - va_start(args, msg); - vfprintf(stderr, msg, args); - va_end(args); - if (status != SESSION_PROBLEM) - fprintf(stderr, "\n"); - - if (status == PARAMETER_PROBLEM) - fprintf(stderr, - "Try `%s help' for more information.\n", - program_name); - } - /* Ignore errors in interactive mode */ - if (status && interactive) { - if (session) - ipset_session_report_reset(session); - return -1; - } - - if (session) - ipset_session_fini(session); - - D("status: %u", status); - exit(status > VERSION_PROBLEM ? OTHER_PROBLEM : status); - /* Unreached */ - return -1; -} - -static int -handle_error(void) -{ - if (ipset_session_warning(session) && - !ipset_envopt_test(session, IPSET_ENV_QUIET)) - fprintf(stderr, "Warning: %s\n", - ipset_session_warning(session)); - if (ipset_session_error(session)) - return exit_error(SESSION_PROBLEM, "%s", - ipset_session_error(session)); - - if (!interactive) { - ipset_session_fini(session); - exit(OTHER_PROBLEM); - } - - ipset_session_report_reset(session); - return -1; -} - -static void -help(void) -{ - const struct ipset_commands *c; - const struct ipset_envopts *opt = ipset_envopts; - - printf("%s v%s\n\n" - "Usage: %s [options] COMMAND\n\nCommands:\n", - program_name, program_version, program_name); - - for (c = ipset_commands; c->cmd; c++) - printf("%s %s\n", c->name[0], c->help); - printf("\nOptions:\n"); - - while (opt->flag) { - if (opt->help) - printf("%s %s\n", opt->name[0], opt->help); - opt++; - } -} - -/* Build faked argv from parsed line */ -static void -build_argv(char *buffer) -{ - char *ptr; - int i; - - /* Reset */ - for (i = 1; i < newargc; i++) - newargv[i] = NULL; - newargc = 1; - - ptr = strtok(buffer, " \t\r\n"); - newargv[newargc++] = ptr; - while ((ptr = strtok(NULL, " \t\r\n")) != NULL) { - if ((newargc + 1) < (int)(sizeof(newargv)/sizeof(char *))) - newargv[newargc++] = ptr; - else { - exit_error(PARAMETER_PROBLEM, - "Line is too long to parse."); - return; - } - } -} - -/* Main parser function, workhorse */ -int parse_commandline(int argc, char *argv[]); - -/* - * Performs a restore from stdin - */ -static int -restore(char *argv0) -{ - int ret = 0; - char *c; - - /* Initialize newargv/newargc */ - newargc = 0; - newargv[newargc++] = argv0; - - while (fgets(cmdline, sizeof(cmdline), stdin)) { - restore_line++; - c = cmdline; - while (isspace(c[0])) - c++; - if (c[0] == '\0' || c[0] == '#') - continue; - else if (STREQ(c, "COMMIT\n") || STREQ(c, "COMMIT\r\n")) { - ret = ipset_commit(session); - if (ret < 0) - handle_error(); - continue; - } - /* Build faked argv, argc */ - build_argv(c); - - /* Execute line */ - ret = parse_commandline(newargc, newargv); - if (ret < 0) - handle_error(); - } - /* implicit "COMMIT" at EOF */ - ret = ipset_commit(session); - if (ret < 0) - handle_error(); - - return ret; -} - -static int -call_parser(int *argc, char *argv[], const struct ipset_arg *args) -{ - int ret = 0; - const struct ipset_arg *arg; - const char *optstr; - - /* Currently CREATE and ADT may have got additional arguments */ - if (!args && *argc > 1) - goto err_unknown; - while (*argc > 1) { - for (arg = args; arg->opt; arg++) { - D("argc: %u, %s vs %s", *argc, argv[1], arg->name[0]); - if (!(ipset_match_option(argv[1], arg->name))) - continue; - - optstr = argv[1]; - /* Shift off matched option */ - D("match %s", arg->name[0]); - ipset_shift_argv(argc, argv, 1); - switch (arg->has_arg) { - case IPSET_MANDATORY_ARG: - if (*argc < 2) - return exit_error(PARAMETER_PROBLEM, - "Missing mandatory argument " - "of option `%s'", - arg->name[0]); - /* Fall through */ - case IPSET_OPTIONAL_ARG: - if (*argc >= 2) { - ret = ipset_call_parser(session, - arg, argv[1]); - if (ret < 0) - return ret; - ipset_shift_argv(argc, argv, 1); - break; - } - /* Fall through */ - default: - ret = ipset_call_parser(session, arg, optstr); - if (ret < 0) - return ret; - } - break; - } - if (!arg->opt) - goto err_unknown; - } - return ret; - -err_unknown: - return exit_error(PARAMETER_PROBLEM, "Unknown argument: `%s'", argv[1]); -} - -static enum ipset_adt -cmd2cmd(int cmd) -{ - switch (cmd) { - case IPSET_CMD_ADD: - return IPSET_ADD; - case IPSET_CMD_DEL: - return IPSET_DEL; - case IPSET_CMD_TEST: - return IPSET_TEST; - case IPSET_CMD_CREATE: - return IPSET_CREATE; - default: - return 0; - } -} - -static void -check_mandatory(const struct ipset_type *type, enum ipset_cmd command) -{ - enum ipset_adt cmd = cmd2cmd(command); - uint64_t flags = ipset_data_flags(ipset_session_data(session)); - uint64_t mandatory = type->mandatory[cmd]; - const struct ipset_arg *arg = type->args[cmd]; - - /* Range can be expressed by ip/cidr */ - if (flags & IPSET_FLAG(IPSET_OPT_CIDR)) - flags |= IPSET_FLAG(IPSET_OPT_IP_TO); - - mandatory &= ~flags; - if (!mandatory) - return; - if (!arg) { - exit_error(OTHER_PROBLEM, - "There are missing mandatory flags " - "but can't check them. " - "It's a bug, please report the problem."); - return; - } - - for (; arg->opt; arg++) - if (mandatory & IPSET_FLAG(arg->opt)) { - exit_error(PARAMETER_PROBLEM, - "Mandatory option `%s' is missing", - arg->name[0]); - return; - } -} - -static const char * -cmd2name(enum ipset_cmd cmd) -{ - const struct ipset_commands *c; - - for (c = ipset_commands; c->cmd; c++) - if (cmd == c->cmd) - return c->name[0]; - return "unknown command"; -} - -static const char * -session_family(void) -{ - switch (ipset_data_family(ipset_session_data(session))) { - case NFPROTO_IPV4: - return "inet"; - case NFPROTO_IPV6: - return "inet6"; - default: - return "unspec"; - } -} - -static void -check_allowed(const struct ipset_type *type, enum ipset_cmd command) -{ - uint64_t flags = ipset_data_flags(ipset_session_data(session)); - enum ipset_adt cmd = cmd2cmd(command); - uint64_t allowed = type->full[cmd]; - uint64_t cmdflags = command == IPSET_CMD_CREATE - ? IPSET_CREATE_FLAGS : IPSET_ADT_FLAGS; - const struct ipset_arg *arg = type->args[cmd]; - enum ipset_opt i; - - /* Range can be expressed by ip/cidr or from-to */ - if (allowed & IPSET_FLAG(IPSET_OPT_IP_TO)) - allowed |= IPSET_FLAG(IPSET_OPT_CIDR); - - for (i = IPSET_OPT_IP; i < IPSET_OPT_FLAGS; i++) { - if (!(cmdflags & IPSET_FLAG(i)) || - (allowed & IPSET_FLAG(i)) || - !(flags & IPSET_FLAG(i))) - continue; - /* Not allowed element-expressions */ - switch (i) { - case IPSET_OPT_CIDR: - exit_error(OTHER_PROBLEM, - "IP/CIDR range is not allowed in command %s " - "with set type %s and family %s", - cmd2name(command), type->name, - session_family()); - return; - case IPSET_OPT_IP_TO: - exit_error(OTHER_PROBLEM, - "FROM-TO IP range is not allowed in command %s " - "with set type %s and family %s", - cmd2name(command), type->name, - session_family()); - return; - case IPSET_OPT_PORT_TO: - exit_error(OTHER_PROBLEM, - "FROM-TO port range is not allowed in command %s " - "with set type %s and family %s", - cmd2name(command), type->name, - session_family()); - return; - default: - break; - } - /* Other options */ - if (!arg) { - exit_error(OTHER_PROBLEM, - "There are not allowed options (%u) " - "but option list is NULL. " - "It's a bug, please report the problem.", i); - return; - } - for (; arg->opt; arg++) { - if (arg->opt != i) - continue; - exit_error(OTHER_PROBLEM, - "%s parameter is not allowed in command %s " - "with set type %s and family %s", - arg->name[0], - cmd2name(command), type->name, - session_family()); - return; - } - exit_error(OTHER_PROBLEM, - "There are not allowed options (%u) " - "but can't resolve them. " - "It's a bug, please report the problem.", i); - return; - } -} - -static const struct ipset_type * -type_find(const char *name) -{ - const struct ipset_type *t = ipset_types(); - - while (t) { - if (ipset_match_typename(name, t)) - return t; - t = t->next; - } - return NULL; -} - -/* Workhorse */ -int -parse_commandline(int argc, char *argv[]) -{ - int ret = 0; - enum ipset_cmd cmd = IPSET_CMD_NONE; - int i; - char *arg0 = NULL, *arg1 = NULL, *c; - const struct ipset_envopts *opt; - const struct ipset_commands *command; - const struct ipset_type *type; - - /* Set session lineno to report parser errors correctly */ - ipset_session_lineno(session, restore_line); - - /* Commandline parsing, somewhat similar to that of 'ip' */ - - /* First: parse core options */ - for (opt = ipset_envopts; opt->flag; opt++) { - for (i = 1; i < argc; ) { - if (!ipset_match_envopt(argv[i], opt->name)) { - i++; - continue; - } - /* Shift off matched option */ - ipset_shift_argv(&argc, argv, i); - switch (opt->has_arg) { - case IPSET_MANDATORY_ARG: - if (i + 1 > argc) - return exit_error(PARAMETER_PROBLEM, - "Missing mandatory argument " - "to option %s", - opt->name[0]); - /* Fall through */ - case IPSET_OPTIONAL_ARG: - if (i + 1 <= argc) { - ret = opt->parse(session, opt->flag, - argv[i]); - if (ret < 0) - return handle_error(); - ipset_shift_argv(&argc, argv, i); - } - break; - case IPSET_NO_ARG: - ret = opt->parse(session, opt->flag, - opt->name[0]); - if (ret < 0) - return handle_error(); - break; - default: - break; - } - } - } - - /* Second: parse command */ - for (command = ipset_commands; - argc > 1 && command->cmd && cmd == IPSET_CMD_NONE; - command++) { - if (!ipset_match_cmd(argv[1], command->name)) - continue; - - if (restore_line != 0 && - (command->cmd == IPSET_CMD_RESTORE || - command->cmd == IPSET_CMD_VERSION || - command->cmd == IPSET_CMD_HELP)) - return exit_error(PARAMETER_PROBLEM, - "Command `%s' is invalid " - "in restore mode.", - command->name[0]); - if (interactive && command->cmd == IPSET_CMD_RESTORE) { - printf("Restore command ignored " - "in interactive mode\n"); - return 0; - } - - /* Shift off matched command arg */ - ipset_shift_argv(&argc, argv, 1); - cmd = command->cmd; - switch (command->has_arg) { - case IPSET_MANDATORY_ARG: - case IPSET_MANDATORY_ARG2: - if (argc < 2) - return exit_error(PARAMETER_PROBLEM, - "Missing mandatory argument " - "to command %s", - command->name[0]); - /* Fall through */ - case IPSET_OPTIONAL_ARG: - arg0 = argv[1]; - if (argc >= 2) - /* Shift off first arg */ - ipset_shift_argv(&argc, argv, 1); - break; - default: - break; - } - if (command->has_arg == IPSET_MANDATORY_ARG2) { - if (argc < 2) - return exit_error(PARAMETER_PROBLEM, - "Missing second mandatory " - "argument to command %s", - command->name[0]); - arg1 = argv[1]; - /* Shift off second arg */ - ipset_shift_argv(&argc, argv, 1); - } - break; - } - - /* Third: catch interactive mode, handle help, version */ - switch (cmd) { - case IPSET_CMD_NONE: - if (interactive) { - printf("No command specified\n"); - return 0; - } - if (argc > 1 && STREQ(argv[1], "-")) { - interactive = true; - printf("%s> ", program_name); - /* Initialize newargv/newargc */ - newargv[newargc++] = program_name; - while (fgets(cmdline, sizeof(cmdline), stdin)) { - c = cmdline; - while (isspace(c[0])) - c++; - if (c[0] == '\0' || c[0] == '#') - continue; - /* Build fake argv, argc */ - build_argv(c); - /* Execute line: ignore errors */ - parse_commandline(newargc, newargv); - printf("%s> ", program_name); - } - return exit_error(NO_PROBLEM, NULL); - } - if (argc > 1) - return exit_error(PARAMETER_PROBLEM, - "No command specified: unknown argument %s", - argv[1]); - return exit_error(PARAMETER_PROBLEM, "No command specified."); - case IPSET_CMD_VERSION: - printf("%s v%s, protocol version: %u\n", - program_name, program_version, IPSET_PROTOCOL); - if (interactive) - return 0; - return exit_error(NO_PROBLEM, NULL); - case IPSET_CMD_HELP: - help(); - - if (interactive || - !ipset_envopt_test(session, IPSET_ENV_QUIET)) { - if (arg0) { - /* Type-specific help, without kernel checking */ - type = type_find(arg0); - if (!type) - return exit_error(PARAMETER_PROBLEM, - "Unknown settype: `%s'", arg0); - printf("\n%s type specific options:\n\n%s", - type->name, type->usage); - if (type->usagefn) - type->usagefn(); - if (type->family == NFPROTO_UNSPEC) - printf("\nType %s is family neutral.\n", - type->name); - else if (type->family == NFPROTO_IPSET_IPV46) - printf("\nType %s supports INET " - "and INET6.\n", - type->name); - else - printf("\nType %s supports family " - "%s only.\n", - type->name, - type->family == NFPROTO_IPV4 - ? "INET" : "INET6"); - } else { - printf("\nSupported set types:\n"); - type = ipset_types(); - while (type) { - printf(" %s\n", type->name); - type = type->next; - } - } - } - if (interactive) - return 0; - return exit_error(NO_PROBLEM, NULL); - case IPSET_CMD_QUIT: - return exit_error(NO_PROBLEM, NULL); - default: - break; - } - - /* Forth: parse command args and issue the command */ - switch (cmd) { - case IPSET_CMD_CREATE: - /* Args: setname typename [type specific options] */ - ret = ipset_parse_setname(session, IPSET_SETNAME, arg0); - if (ret < 0) - return handle_error(); - - ret = ipset_parse_typename(session, IPSET_OPT_TYPENAME, arg1); - if (ret < 0) - return handle_error(); - - type = ipset_type_get(session, cmd); - if (type == NULL) - return handle_error(); - - /* Parse create options */ - ret = call_parser(&argc, argv, type->args[IPSET_CREATE]); - if (ret < 0) - return handle_error(); - else if (ret) - return ret; - - /* Check mandatory, then allowed options */ - check_mandatory(type, cmd); - check_allowed(type, cmd); - - break; - case IPSET_CMD_DESTROY: - case IPSET_CMD_FLUSH: - case IPSET_CMD_LIST: - case IPSET_CMD_SAVE: - /* Args: [setname] */ - if (arg0) { - ret = ipset_parse_setname(session, - IPSET_SETNAME, arg0); - if (ret < 0) - return handle_error(); - } - break; - - case IPSET_CMD_RENAME: - case IPSET_CMD_SWAP: - /* Args: from-setname to-setname */ - ret = ipset_parse_setname(session, IPSET_SETNAME, arg0); - if (ret < 0) - return handle_error(); - ret = ipset_parse_setname(session, IPSET_OPT_SETNAME2, arg1); - if (ret < 0) - return handle_error(); - break; - - case IPSET_CMD_RESTORE: - /* Restore mode */ - if (argc > 1) - return exit_error(PARAMETER_PROBLEM, - "Unknown argument %s", argv[1]); - return restore(argv[0]); - case IPSET_CMD_ADD: - case IPSET_CMD_DEL: - case IPSET_CMD_TEST: - D("ADT: setname %s", arg0); - /* Args: setname ip [options] */ - ret = ipset_parse_setname(session, IPSET_SETNAME, arg0); - if (ret < 0) - return handle_error(); - - type = ipset_type_get(session, cmd); - if (type == NULL) - return handle_error(); - - ret = ipset_parse_elem(session, type->last_elem_optional, arg1); - if (ret < 0) - return handle_error(); - - /* Parse additional ADT options */ - ret = call_parser(&argc, argv, type->args[cmd2cmd(cmd)]); - if (ret < 0) - return handle_error(); - else if (ret) - return ret; - - /* Check mandatory, then allowed options */ - check_mandatory(type, cmd); - check_allowed(type, cmd); - - break; - default: - break; - } - - if (argc > 1) - return exit_error(PARAMETER_PROBLEM, - "Unknown argument %s", argv[1]); - ret = ipset_cmd(session, cmd, restore_line); - D("ret %d", ret); - /* Special case for TEST and non-quiet mode */ - if (cmd == IPSET_CMD_TEST && ipset_session_warning(session)) { - if (!ipset_envopt_test(session, IPSET_ENV_QUIET)) - fprintf(stderr, "%s", ipset_session_warning(session)); - ipset_session_report_reset(session); - } - if (ret < 0) - handle_error(); - - return ret; -} - -int -main(int argc, char *argv[]) -{ - int ret; - - /* Register types */ - ipset_type_add(&ipset_bitmap_ip0); - ipset_type_add(&ipset_bitmap_ipmac0); - ipset_type_add(&ipset_bitmap_port0); - ipset_type_add(&ipset_hash_ip0); - ipset_type_add(&ipset_hash_net0); - ipset_type_add(&ipset_hash_net1); - ipset_type_add(&ipset_hash_netport1); - ipset_type_add(&ipset_hash_netport2); - ipset_type_add(&ipset_hash_netiface0); - ipset_type_add(&ipset_hash_ipport1); - ipset_type_add(&ipset_hash_ipportip1); - ipset_type_add(&ipset_hash_ipportnet1); - ipset_type_add(&ipset_hash_ipportnet2); - ipset_type_add(&ipset_list_set0); - - /* Initialize session */ - session = ipset_session_init(printf); - if (session == NULL) - return exit_error(OTHER_PROBLEM, - "Cannot initialize ipset session, aborting."); - - ret = parse_commandline(argc, argv); - - ipset_session_fini(session); - - return ret; -} diff --git a/extensions/ipset-6/src/ipset_bitmap_ip.c b/extensions/ipset-6/src/ipset_bitmap_ip.c deleted file mode 100644 index 8b8220d..0000000 --- a/extensions/ipset-6/src/ipset_bitmap_ip.c +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* IPSET_OPT_* */ -#include /* parser functions */ -#include /* printing functions */ -#include /* prototypes */ - -/* Parse commandline arguments */ -static const struct ipset_arg bitmap_ip_create_args[] = { - { .name = { "range", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_netrange, .print = ipset_print_ip, - }, - { .name = { "netmask", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_NETMASK, - .parse = ipset_parse_netmask, .print = ipset_print_number, - }, - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - /* Backward compatibility */ - { .name = { "from", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_single_ip, - }, - { .name = { "to", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO, - .parse = ipset_parse_single_ip, - }, - { .name = { "network", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_net, - }, - { }, -}; - -static const struct ipset_arg bitmap_ip_add_args[] = { - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const char bitmap_ip_usage[] = -"create SETNAME bitmap:ip range IP/CIDR|FROM-TO\n" -" [netmask CIDR] [timeout VALUE]\n" -"add SETNAME IP|IP/CIDR|FROM-TO [timeout VALUE]\n" -"del SETNAME IP|IP/CIDR|FROM-TO\n" -"test SETNAME IP\n\n" -"where IP, FROM and TO are IPv4 addresses (or hostnames),\n" -" CIDR is a valid IPv4 CIDR prefix.\n"; - -struct ipset_type ipset_bitmap_ip0 = { - .name = "bitmap:ip", - .alias = { "ipmap", NULL }, - .revision = 0, - .family = NFPROTO_IPV4, - .dimension = IPSET_DIM_ONE, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_ip, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - }, - .args = { - [IPSET_CREATE] = bitmap_ip_create_args, - [IPSET_ADD] = bitmap_ip_add_args, - }, - .mandatory = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_NETMASK) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), - }, - - .usage = bitmap_ip_usage, -}; diff --git a/extensions/ipset-6/src/ipset_bitmap_ipmac.c b/extensions/ipset-6/src/ipset_bitmap_ipmac.c deleted file mode 100644 index d822bf6..0000000 --- a/extensions/ipset-6/src/ipset_bitmap_ipmac.c +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* IPSET_OPT_* */ -#include /* parser functions */ -#include /* printing functions */ -#include /* prototypes */ - -/* Parse commandline arguments */ -static const struct ipset_arg bitmap_ipmac_create_args[] = { - { .name = { "range", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_netrange, .print = ipset_print_ip, - }, - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - /* Backward compatibility */ - { .name = { "from", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_single_ip, - }, - { .name = { "to", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO, - .parse = ipset_parse_single_ip, - }, - { .name = { "network", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_net, - }, - { }, -}; - -static const struct ipset_arg bitmap_ipmac_add_args[] = { - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const char bitmap_ipmac_usage[] = -"create SETNAME bitmap:ip,mac range IP/CIDR|FROM-TO\n" -" [matchunset] [timeout VALUE]\n" -"add SETNAME IP[,MAC] [timeout VALUE]\n" -"del SETNAME IP[,MAC]\n" -"test SETNAME IP[,MAC]\n\n" -"where IP, FROM and TO are IPv4 addresses (or hostnames),\n" -" CIDR is a valid IPv4 CIDR prefix,\n" -" MAC is a valid MAC address.\n"; - -struct ipset_type ipset_bitmap_ipmac0 = { - .name = "bitmap:ip,mac", - .alias = { "macipmap", NULL }, - .revision = 0, - .family = NFPROTO_IPV4, - .dimension = IPSET_DIM_TWO, - .last_elem_optional = true, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_single_ip, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - [IPSET_DIM_TWO - 1] = { - .parse = ipset_parse_ether, - .print = ipset_print_ether, - .opt = IPSET_OPT_ETHER - }, - }, - .args = { - [IPSET_CREATE] = bitmap_ipmac_create_args, - [IPSET_ADD] = bitmap_ipmac_add_args, - }, - .mandatory = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_ETHER) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_ETHER), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_ETHER), - }, - - .usage = bitmap_ipmac_usage, -}; diff --git a/extensions/ipset-6/src/ipset_bitmap_port.c b/extensions/ipset-6/src/ipset_bitmap_port.c deleted file mode 100644 index 69be809..0000000 --- a/extensions/ipset-6/src/ipset_bitmap_port.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* IPSET_OPT_* */ -#include /* parser functions */ -#include /* printing functions */ -#include /* prototypes */ - -/* Parse commandline arguments */ -static const struct ipset_arg bitmap_port_create_args[] = { - { .name = { "range", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PORT, - .parse = ipset_parse_tcp_port, .print = ipset_print_port, - }, - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - /* Backward compatibility */ - { .name = { "from", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PORT, - .parse = ipset_parse_single_tcp_port, - }, - { .name = { "to", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PORT_TO, - .parse = ipset_parse_single_tcp_port, - }, - { }, -}; - -static const struct ipset_arg bitmap_port_add_args[] = { - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const char bitmap_port_usage[] = -"create SETNAME bitmap:port range FROM-TO\n" -" [timeout VALUE]\n" -"add SETNAME PORT|FROM-TO [timeout VALUE]\n" -"del SETNAME PORT|FROM-TO\n" -"test SETNAME PORT\n\n" -"where PORT, FROM and TO are port numbers or port names from /etc/services.\n"; - -struct ipset_type ipset_bitmap_port0 = { - .name = "bitmap:port", - .alias = { "portmap", NULL }, - .revision = 0, - .family = NFPROTO_UNSPEC, - .dimension = IPSET_DIM_ONE, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_tcp_port, - .print = ipset_print_port, - .opt = IPSET_OPT_PORT - }, - }, - .args = { - [IPSET_CREATE] = bitmap_port_create_args, - [IPSET_ADD] = bitmap_port_add_args, - }, - .mandatory = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_PORT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_PORT), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_PORT), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_PORT), - }, - - .usage = bitmap_port_usage, -}; diff --git a/extensions/ipset-6/src/ipset_hash_ip.c b/extensions/ipset-6/src/ipset_hash_ip.c deleted file mode 100644 index 912b991..0000000 --- a/extensions/ipset-6/src/ipset_hash_ip.c +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* IPSET_OPT_* */ -#include /* parser functions */ -#include /* printing functions */ -#include /* prototypes */ - -/* Parse commandline arguments */ -static const struct ipset_arg hash_ip_create_args[] = { - { .name = { "family", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, .print = ipset_print_family, - }, - /* Alias: family inet */ - { .name = { "-4", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - /* Alias: family inet6 */ - { .name = { "-6", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - { .name = { "hashsize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "maxelem", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "netmask", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_NETMASK, - .parse = ipset_parse_netmask, .print = ipset_print_number, - }, - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - /* Ignored options: backward compatibilty */ - { .name = { "probes", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, - .parse = ipset_parse_ignored, .print = ipset_print_number, - }, - { .name = { "resize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE, - .parse = ipset_parse_ignored, .print = ipset_print_number, - }, - { .name = { "gc", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_GC, - .parse = ipset_parse_ignored, .print = ipset_print_number, - }, - { }, -}; - -static const struct ipset_arg hash_ip_add_args[] = { - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const char hash_ip_usage[] = -"create SETNAME hash:ip\n" -" [family inet|inet6]\n" -" [hashsize VALUE] [maxelem VALUE]\n" -" [netmask CIDR] [timeout VALUE]\n" -"add SETNAME IP [timeout VALUE]\n" -"del SETNAME IP\n" -"test SETNAME IP\n\n" -"where depending on the INET family\n" -" IP is a valid IPv4 or IPv6 address (or hostname),\n" -" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n" -" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n" -" is supported for IPv4.\n"; - -struct ipset_type ipset_hash_ip0 = { - .name = "hash:ip", - .alias = { "iphash", NULL }, - .revision = 0, - .family = NFPROTO_IPSET_IPV46, - .dimension = IPSET_DIM_ONE, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_ip4_single6, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - }, - .args = { - [IPSET_CREATE] = hash_ip_create_args, - [IPSET_ADD] = hash_ip_add_args, - }, - .mandatory = { - [IPSET_CREATE] = 0, - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) - | IPSET_FLAG(IPSET_OPT_MAXELEM) - | IPSET_FLAG(IPSET_OPT_NETMASK) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), - }, - - .usage = hash_ip_usage, -}; diff --git a/extensions/ipset-6/src/ipset_hash_ipport.c b/extensions/ipset-6/src/ipset_hash_ipport.c deleted file mode 100644 index 748e452..0000000 --- a/extensions/ipset-6/src/ipset_hash_ipport.c +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* IPSET_OPT_* */ -#include /* parser functions */ -#include /* printing functions */ -#include /* ipset_port_usage */ -#include /* prototypes */ - -/* Parse commandline arguments */ -static const struct ipset_arg hash_ipport_create_args[] = { - { .name = { "family", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, .print = ipset_print_family, - }, - /* Alias: family inet */ - { .name = { "-4", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - /* Alias: family inet6 */ - { .name = { "-6", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - { .name = { "hashsize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "maxelem", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - /* Backward compatibility */ - { .name = { "probes", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, - .parse = ipset_parse_ignored, .print = ipset_print_number, - }, - { .name = { "resize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE, - .parse = ipset_parse_ignored, .print = ipset_print_number, - }, - { .name = { "from", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_ignored, - }, - { .name = { "to", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO, - .parse = ipset_parse_ignored, - }, - { .name = { "network", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_ignored, - }, - { }, -}; - -static const struct ipset_arg hash_ipport_add_args[] = { - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const char hash_ipport1_usage[] = -"create SETNAME hash:ip,port\n" -" [family inet|inet6]\n" -" [hashsize VALUE] [maxelem VALUE]\n" -" [timeout VALUE]\n" -"add SETNAME IP,PROTO:PORT [timeout VALUE]\n" -"del SETNAME IP,PROTO:PORT\n" -"test SETNAME IP,PROTO:PORT\n\n" -"where depending on the INET family\n" -" IP is a valid IPv4 or IPv6 address (or hostname).\n" -" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n" -" is supported for IPv4.\n" -" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n" -" port range is supported both for IPv4 and IPv6.\n"; - -struct ipset_type ipset_hash_ipport1 = { - .name = "hash:ip,port", - .alias = { "ipporthash", NULL }, - .revision = 1, - .family = NFPROTO_IPSET_IPV46, - .dimension = IPSET_DIM_TWO, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_ip4_single6, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - [IPSET_DIM_TWO - 1] = { - .parse = ipset_parse_proto_port, - .print = ipset_print_proto_port, - .opt = IPSET_OPT_PORT - }, - }, - .args = { - [IPSET_CREATE] = hash_ipport_create_args, - [IPSET_ADD] = hash_ipport_add_args, - }, - .mandatory = { - [IPSET_CREATE] = 0, - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_PORT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_PORT), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_PORT), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) - | IPSET_FLAG(IPSET_OPT_MAXELEM) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO), - }, - - .usage = hash_ipport1_usage, - .usagefn = ipset_port_usage, -}; diff --git a/extensions/ipset-6/src/ipset_hash_ipportip.c b/extensions/ipset-6/src/ipset_hash_ipportip.c deleted file mode 100644 index 7c046a3..0000000 --- a/extensions/ipset-6/src/ipset_hash_ipportip.c +++ /dev/null @@ -1,155 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* IPSET_OPT_* */ -#include /* parser functions */ -#include /* printing functions */ -#include /* ipset_port_usage */ -#include /* prototypes */ - -/* Parse commandline arguments */ -static const struct ipset_arg hash_ipportip_create_args[] = { - { .name = { "family", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, .print = ipset_print_family, - }, - /* Alias: family inet */ - { .name = { "-4", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - /* Alias: family inet6 */ - { .name = { "-6", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - { .name = { "hashsize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "maxelem", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - /* Backward compatibility */ - { .name = { "probes", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, - .parse = ipset_parse_ignored, .print = ipset_print_number, - }, - { .name = { "resize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE, - .parse = ipset_parse_ignored, .print = ipset_print_number, - }, - { .name = { "from", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_ignored, - }, - { .name = { "to", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO, - .parse = ipset_parse_ignored, - }, - { .name = { "network", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_ignored, - }, - { }, -}; - -static const struct ipset_arg hash_ipportip_add_args[] = { - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const char hash_ipportip1_usage[] = -"create SETNAME hash:ip,port,ip\n" -" [family inet|inet6]\n" -" [hashsize VALUE] [maxelem VALUE]\n" -" [timeout VALUE]\n" -"add SETNAME IP,PROTO:PORT,IP [timeout VALUE]\n" -"del SETNAME IP,PROTO:PORT,IP\n" -"test SETNAME IP,PROTO:PORT,IP\n\n" -"where depending on the INET family\n" -" IP is a valid IPv4 or IPv6 address (or hostname).\n" -" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n" -" in the first IP component is supported for IPv4.\n" -" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n" -" port range is supported both for IPv4 and IPv6.\n"; - -struct ipset_type ipset_hash_ipportip1 = { - .name = "hash:ip,port,ip", - .alias = { "ipportiphash", NULL }, - .revision = 1, - .family = NFPROTO_IPSET_IPV46, - .dimension = IPSET_DIM_THREE, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_ip4_single6, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - [IPSET_DIM_TWO - 1] = { - .parse = ipset_parse_proto_port, - .print = ipset_print_proto_port, - .opt = IPSET_OPT_PORT - }, - [IPSET_DIM_THREE - 1] = { - .parse = ipset_parse_single_ip, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP2 - }, - }, - .args = { - [IPSET_CREATE] = hash_ipportip_create_args, - [IPSET_ADD] = hash_ipportip_add_args, - }, - .mandatory = { - [IPSET_CREATE] = 0, - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) - | IPSET_FLAG(IPSET_OPT_MAXELEM) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2), - }, - - .usage = hash_ipportip1_usage, - .usagefn = ipset_port_usage, -}; diff --git a/extensions/ipset-6/src/ipset_hash_ipportnet.c b/extensions/ipset-6/src/ipset_hash_ipportnet.c deleted file mode 100644 index c4cf97e..0000000 --- a/extensions/ipset-6/src/ipset_hash_ipportnet.c +++ /dev/null @@ -1,254 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* IPSET_OPT_* */ -#include /* parser functions */ -#include /* printing functions */ -#include /* ipset_port_usage */ -#include /* prototypes */ - -/* Parse commandline arguments */ -static const struct ipset_arg hash_ipportnet_create_args[] = { - { .name = { "family", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, .print = ipset_print_family, - }, - /* Alias: family inet */ - { .name = { "-4", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - /* Alias: family inet6 */ - { .name = { "-6", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - { .name = { "hashsize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "maxelem", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - /* Backward compatibility */ - { .name = { "probes", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, - .parse = ipset_parse_ignored, .print = ipset_print_number, - }, - { .name = { "resize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE, - .parse = ipset_parse_ignored, .print = ipset_print_number, - }, - { .name = { "from", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_ignored, - }, - { .name = { "to", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP_TO, - .parse = ipset_parse_ignored, - }, - { .name = { "network", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_IP, - .parse = ipset_parse_ignored, - }, - { }, -}; - -static const struct ipset_arg hash_ipportnet_add_args[] = { - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const char hash_ipportnet1_usage[] = -"create SETNAME hash:ip,port,net\n" -" [family inet|inet6]\n" -" [hashsize VALUE] [maxelem VALUE]\n" -" [timeout VALUE]\n" -"add SETNAME IP,PROTO:PORT,IP[/CIDR] [timeout VALUE]\n" -"del SETNAME IP,PROTO:PORT,IP[/CIDR]\n" -"test SETNAME IP,PROTO:PORT,IP[/CIDR]\n\n" -"where depending on the INET family\n" -" IP are valid IPv4 or IPv6 addresses (or hostnames),\n" -" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n" -" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n" -" in the first IP component is supported for IPv4.\n" -" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n" -" port range is supported both for IPv4 and IPv6.\n"; - -struct ipset_type ipset_hash_ipportnet1 = { - .name = "hash:ip,port,net", - .alias = { "ipportnethash", NULL }, - .revision = 1, - .family = NFPROTO_IPSET_IPV46, - .dimension = IPSET_DIM_THREE, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_ip4_single6, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - [IPSET_DIM_TWO - 1] = { - .parse = ipset_parse_proto_port, - .print = ipset_print_proto_port, - .opt = IPSET_OPT_PORT - }, - [IPSET_DIM_THREE - 1] = { - .parse = ipset_parse_ipnet, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP2 - }, - }, - .args = { - [IPSET_CREATE] = hash_ipportnet_create_args, - [IPSET_ADD] = hash_ipportnet_add_args, - }, - .mandatory = { - [IPSET_CREATE] = 0, - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) - | IPSET_FLAG(IPSET_OPT_MAXELEM) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2) - | IPSET_FLAG(IPSET_OPT_CIDR2) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2) - | IPSET_FLAG(IPSET_OPT_CIDR2), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2) - | IPSET_FLAG(IPSET_OPT_CIDR2), - }, - - .usage = hash_ipportnet1_usage, - .usagefn = ipset_port_usage, -}; - -static const char hash_ipportnet2_usage[] = -"create SETNAME hash:ip,port,net\n" -" [family inet|inet6]\n" -" [hashsize VALUE] [maxelem VALUE]\n" -" [timeout VALUE]\n" -"add SETNAME IP,PROTO:PORT,IP[/CIDR] [timeout VALUE]\n" -"del SETNAME IP,PROTO:PORT,IP[/CIDR]\n" -"test SETNAME IP,PROTO:PORT,IP[/CIDR]\n\n" -"where depending on the INET family\n" -" IP are valid IPv4 or IPv6 addresses (or hostnames),\n" -" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n" -" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n" -" in both IP components are supported for IPv4.\n" -" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n" -" port range is supported both for IPv4 and IPv6.\n"; - -struct ipset_type ipset_hash_ipportnet2 = { - .name = "hash:ip,port,net", - .alias = { "ipportnethash", NULL }, - .revision = 2, - .family = NFPROTO_IPSET_IPV46, - .dimension = IPSET_DIM_THREE, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_ip4_single6, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - [IPSET_DIM_TWO - 1] = { - .parse = ipset_parse_proto_port, - .print = ipset_print_proto_port, - .opt = IPSET_OPT_PORT - }, - [IPSET_DIM_THREE - 1] = { - .parse = ipset_parse_ip4_net6, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP2 - }, - }, - .args = { - [IPSET_CREATE] = hash_ipportnet_create_args, - [IPSET_ADD] = hash_ipportnet_add_args, - }, - .mandatory = { - [IPSET_CREATE] = 0, - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) - | IPSET_FLAG(IPSET_OPT_MAXELEM) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2) - | IPSET_FLAG(IPSET_OPT_CIDR2) - | IPSET_FLAG(IPSET_OPT_IP2_TO) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2) - | IPSET_FLAG(IPSET_OPT_CIDR2) - | IPSET_FLAG(IPSET_OPT_IP2_TO), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_IP2) - | IPSET_FLAG(IPSET_OPT_CIDR2), - }, - - .usage = hash_ipportnet2_usage, - .usagefn = ipset_port_usage, -}; - diff --git a/extensions/ipset-6/src/ipset_hash_net.c b/extensions/ipset-6/src/ipset_hash_net.c deleted file mode 100644 index 76269f0..0000000 --- a/extensions/ipset-6/src/ipset_hash_net.c +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* IPSET_OPT_* */ -#include /* parser functions */ -#include /* printing functions */ -#include /* prototypes */ - -/* Parse commandline arguments */ -static const struct ipset_arg hash_net_create_args[] = { - { .name = { "family", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, .print = ipset_print_family, - }, - /* Alias: family inet */ - { .name = { "-4", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - /* Alias: family inet6 */ - { .name = { "-6", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - { .name = { "hashsize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "maxelem", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - /* Ignored options: backward compatibilty */ - { .name = { "probes", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES, - .parse = ipset_parse_ignored, .print = ipset_print_number, - }, - { .name = { "resize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_RESIZE, - .parse = ipset_parse_ignored, .print = ipset_print_number, - }, - { }, -}; - -static const struct ipset_arg hash_net_add_args[] = { - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const char hash_net0_usage[] = -"create SETNAME hash:net\n" -" [family inet|inet6]\n" -" [hashsize VALUE] [maxelem VALUE]\n" -" [timeout VALUE]\n" -"add SETNAME IP[/CIDR] [timeout VALUE]\n" -"del SETNAME IP[/CIDR]\n" -"test SETNAME IP[/CIDR]\n\n" -"where depending on the INET family\n" -" IP is an IPv4 or IPv6 address (or hostname),\n" -" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"; - -struct ipset_type ipset_hash_net0 = { - .name = "hash:net", - .alias = { "nethash", NULL }, - .revision = 0, - .family = NFPROTO_IPSET_IPV46, - .dimension = IPSET_DIM_ONE, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_ipnet, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - }, - .args = { - [IPSET_CREATE] = hash_net_create_args, - [IPSET_ADD] = hash_net_add_args, - }, - .mandatory = { - [IPSET_CREATE] = 0, - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) - | IPSET_FLAG(IPSET_OPT_MAXELEM) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR), - }, - - .usage = hash_net0_usage, -}; - -static const char hash_net1_usage[] = -"create SETNAME hash:net\n" -" [family inet|inet6]\n" -" [hashsize VALUE] [maxelem VALUE]\n" -" [timeout VALUE]\n" -"add SETNAME IP[/CIDR]|FROM-TO [timeout VALUE]\n" -"del SETNAME IP[/CIDR]|FROM-TO\n" -"test SETNAME IP[/CIDR]\n\n" -"where depending on the INET family\n" -" IP is an IPv4 or IPv6 address (or hostname),\n" -" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n" -" IP range is not supported with IPv6.\n"; - -struct ipset_type ipset_hash_net1 = { - .name = "hash:net", - .alias = { "nethash", NULL }, - .revision = 1, - .family = NFPROTO_IPSET_IPV46, - .dimension = IPSET_DIM_ONE, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_ip4_net6, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - }, - .args = { - [IPSET_CREATE] = hash_net_create_args, - [IPSET_ADD] = hash_net_add_args, - }, - .mandatory = { - [IPSET_CREATE] = 0, - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) - | IPSET_FLAG(IPSET_OPT_MAXELEM) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_IP_TO), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR), - }, - - .usage = hash_net1_usage, -}; - diff --git a/extensions/ipset-6/src/ipset_hash_netiface.c b/extensions/ipset-6/src/ipset_hash_netiface.c deleted file mode 100644 index 51d9cad..0000000 --- a/extensions/ipset-6/src/ipset_hash_netiface.c +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2011 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* IPSET_OPT_* */ -#include /* parser functions */ -#include /* printing functions */ -#include /* ipset_port_usage */ -#include /* prototypes */ - -/* Parse commandline arguments */ -static const struct ipset_arg hash_netiface_create_args[] = { - { .name = { "family", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, .print = ipset_print_family, - }, - /* Alias: family inet */ - { .name = { "-4", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - /* Alias: family inet6 */ - { .name = { "-6", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - { .name = { "hashsize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "maxelem", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const struct ipset_arg hash_netiface_add_args[] = { - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const char hash_netiface_usage[] = -"create SETNAME hash:net,iface\n" -" [family inet|inet6]\n" -" [hashsize VALUE] [maxelem VALUE]\n" -" [timeout VALUE]\n" -"add SETNAME IP[/CIDR]|FROM-TO,[physdev:]IFACE [timeout VALUE]\n" -"del SETNAME IP[/CIDR]|FROM-TO,[physdev:]IFACE\n" -"test SETNAME IP[/CIDR],[physdev:]IFACE\n\n" -"where depending on the INET family\n" -" IP is a valid IPv4 or IPv6 address (or hostname),\n" -" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n" -" Adding/deleting multiple elements with IPv4 is supported.\n"; - -struct ipset_type ipset_hash_netiface0 = { - .name = "hash:net,iface", - .alias = { "netifacehash", NULL }, - .revision = 0, - .family = NFPROTO_IPSET_IPV46, - .dimension = IPSET_DIM_TWO, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_ip4_net6, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - [IPSET_DIM_TWO - 1] = { - .parse = ipset_parse_iface, - .print = ipset_print_iface, - .opt = IPSET_OPT_IFACE - }, - }, - .args = { - [IPSET_CREATE] = hash_netiface_create_args, - [IPSET_ADD] = hash_netiface_add_args, - }, - .mandatory = { - [IPSET_CREATE] = 0, - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IFACE), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IFACE), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_IFACE), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) - | IPSET_FLAG(IPSET_OPT_MAXELEM) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_IFACE) - | IPSET_FLAG(IPSET_OPT_PHYSDEV) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_IFACE) - | IPSET_FLAG(IPSET_OPT_PHYSDEV), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_IFACE) - | IPSET_FLAG(IPSET_OPT_PHYSDEV), - }, - - .usage = hash_netiface_usage, -}; - diff --git a/extensions/ipset-6/src/ipset_hash_netport.c b/extensions/ipset-6/src/ipset_hash_netport.c deleted file mode 100644 index af6adf1..0000000 --- a/extensions/ipset-6/src/ipset_hash_netport.c +++ /dev/null @@ -1,199 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* IPSET_OPT_* */ -#include /* parser functions */ -#include /* printing functions */ -#include /* ipset_port_usage */ -#include /* prototypes */ - -/* Parse commandline arguments */ -static const struct ipset_arg hash_netport_create_args[] = { - { .name = { "family", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, .print = ipset_print_family, - }, - /* Alias: family inet */ - { .name = { "-4", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - /* Alias: family inet6 */ - { .name = { "-6", NULL }, - .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY, - .parse = ipset_parse_family, - }, - { .name = { "hashsize", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "maxelem", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const struct ipset_arg hash_netport_add_args[] = { - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const char hash_netport1_usage[] = -"create SETNAME hash:net,port\n" -" [family inet|inet6]\n" -" [hashsize VALUE] [maxelem VALUE]\n" -" [timeout VALUE]\n" -"add SETNAME IP[/CIDR],PROTO:PORT [timeout VALUE]\n" -"del SETNAME IP[/CIDR],PROTO:PORT\n" -"test SETNAME IP[/CIDR],PROTO:PORT\n\n" -"where depending on the INET family\n" -" IP is a valid IPv4 or IPv6 address (or hostname),\n" -" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n" -" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n" -" port range is supported both for IPv4 and IPv6.\n"; - -struct ipset_type ipset_hash_netport1 = { - .name = "hash:net,port", - .alias = { "netporthash", NULL }, - .revision = 1, - .family = NFPROTO_IPSET_IPV46, - .dimension = IPSET_DIM_TWO, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_ipnet, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - [IPSET_DIM_TWO - 1] = { - .parse = ipset_parse_proto_port, - .print = ipset_print_proto_port, - .opt = IPSET_OPT_PORT - }, - }, - .args = { - [IPSET_CREATE] = hash_netport_create_args, - [IPSET_ADD] = hash_netport_add_args, - }, - .mandatory = { - [IPSET_CREATE] = 0, - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_PORT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_PORT), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_PORT), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) - | IPSET_FLAG(IPSET_OPT_MAXELEM) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_TIMEOUT) - | IPSET_FLAG(IPSET_OPT_CIDR), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_CIDR), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_CIDR), - }, - - .usage = hash_netport1_usage, - .usagefn = ipset_port_usage, -}; - -static const char hash_netport2_usage[] = -"create SETNAME hash:net,port\n" -" [family inet|inet6]\n" -" [hashsize VALUE] [maxelem VALUE]\n" -" [timeout VALUE]\n" -"add SETNAME IP[/CIDR]|FROM-TO,PROTO:PORT [timeout VALUE]\n" -"del SETNAME IP[/CIDR]|FROM-TO,PROTO:PORT\n" -"test SETNAME IP[/CIDR],PROTO:PORT\n\n" -"where depending on the INET family\n" -" IP is a valid IPv4 or IPv6 address (or hostname),\n" -" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n" -" Adding/deleting multiple elements with IPv4 is supported.\n" -" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n" -" port range is supported both for IPv4 and IPv6.\n"; - -struct ipset_type ipset_hash_netport2 = { - .name = "hash:net,port", - .alias = { "netporthash", NULL }, - .revision = 2, - .family = NFPROTO_IPSET_IPV46, - .dimension = IPSET_DIM_TWO, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_ip4_net6, - .print = ipset_print_ip, - .opt = IPSET_OPT_IP - }, - [IPSET_DIM_TWO - 1] = { - .parse = ipset_parse_proto_port, - .print = ipset_print_proto_port, - .opt = IPSET_OPT_PORT - }, - }, - .args = { - [IPSET_CREATE] = hash_netport_create_args, - [IPSET_ADD] = hash_netport_add_args, - }, - .mandatory = { - [IPSET_CREATE] = 0, - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_PORT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_PORT), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_PORT), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE) - | IPSET_FLAG(IPSET_OPT_MAXELEM) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_IP_TO) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PORT_TO) - | IPSET_FLAG(IPSET_OPT_PROTO), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP) - | IPSET_FLAG(IPSET_OPT_CIDR) - | IPSET_FLAG(IPSET_OPT_PORT) - | IPSET_FLAG(IPSET_OPT_PROTO), - }, - - .usage = hash_netport2_usage, - .usagefn = ipset_port_usage, -}; diff --git a/extensions/ipset-6/src/ipset_list_set.c b/extensions/ipset-6/src/ipset_list_set.c deleted file mode 100644 index d95290b..0000000 --- a/extensions/ipset-6/src/ipset_list_set.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* IPSET_OPT_* */ -#include /* parser functions */ -#include /* printing functions */ -#include /* prototypes */ - -/* Parse commandline arguments */ -static const struct ipset_arg list_set_create_args[] = { - { .name = { "size", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_SIZE, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { }, -}; - -static const struct ipset_arg list_set_adt_args[] = { - { .name = { "timeout", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT, - .parse = ipset_parse_uint32, .print = ipset_print_number, - }, - { .name = { "before", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_NAMEREF, - .parse = ipset_parse_before, - }, - { .name = { "after", NULL }, - .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_NAMEREF, - .parse = ipset_parse_after, - }, - { }, -}; - -static const char list_set_usage[] = -"create SETNAME list:set\n" -" [size VALUE] [timeout VALUE]\n" -"add SETNAME NAME [before|after NAME] [timeout VALUE]\n" -"del SETNAME NAME [before|after NAME]\n" -"test SETNAME NAME [before|after NAME]\n\n" -"where NAME are existing set names.\n"; - -struct ipset_type ipset_list_set0 = { - .name = "list:set", - .alias = { "setlist", NULL }, - .revision = 0, - .family = NFPROTO_UNSPEC, - .dimension = IPSET_DIM_ONE, - .elem = { - [IPSET_DIM_ONE - 1] = { - .parse = ipset_parse_setname, - .print = ipset_print_name, - .opt = IPSET_OPT_NAME - }, - }, - .compat_parse_elem = ipset_parse_name_compat, - .args = { - [IPSET_CREATE] = list_set_create_args, - [IPSET_ADD] = list_set_adt_args, - [IPSET_DEL] = list_set_adt_args, - [IPSET_TEST] = list_set_adt_args, - }, - .mandatory = { - [IPSET_CREATE] = 0, - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_NAME), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_NAME), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_NAME), - }, - .full = { - [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_SIZE) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_NAME) - | IPSET_FLAG(IPSET_OPT_BEFORE) - | IPSET_FLAG(IPSET_OPT_NAMEREF) - | IPSET_FLAG(IPSET_OPT_TIMEOUT), - [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_NAME) - | IPSET_FLAG(IPSET_OPT_BEFORE) - | IPSET_FLAG(IPSET_OPT_NAMEREF), - [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_NAME) - | IPSET_FLAG(IPSET_OPT_BEFORE) - | IPSET_FLAG(IPSET_OPT_NAMEREF), - }, - - .usage = list_set_usage, -}; diff --git a/extensions/ipset-6/src/ui.c b/extensions/ipset-6/src/ui.c deleted file mode 100644 index 2c4884d..0000000 --- a/extensions/ipset-6/src/ui.c +++ /dev/null @@ -1,289 +0,0 @@ -/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include /* assert */ -#include /* tolower */ -#include /* memcmp, str* */ - -#include /* IPSET_CMD_* */ -#include /* id_to_icmp */ -#include /* id_to_icmpv6 */ -#include /* IPSET_*_ARG */ -#include /* ipset_envopt_parse */ -#include /* ipset_parse_family */ -#include /* ipset_print_family */ -#include /* STREQ */ -#include /* prototypes */ - -/* Commands and environment options */ - -const struct ipset_commands ipset_commands[] = { - /* Order is important */ - - { /* c[reate], --create, n[ew], -N */ - .cmd = IPSET_CMD_CREATE, - .name = { "create", "new" }, - .has_arg = IPSET_MANDATORY_ARG2, - .help = "SETNAME TYPENAME [type-specific-options]\n" - " Create a new set", - }, - { /* a[dd], --add, -A */ - .cmd = IPSET_CMD_ADD, - .name = { "add", NULL }, - .has_arg = IPSET_MANDATORY_ARG2, - .help = "SETNAME ENTRY\n" - " Add entry to the named set", - }, - { /* d[el], --del, -D */ - .cmd = IPSET_CMD_DEL, - .name = { "del", NULL }, - .has_arg = IPSET_MANDATORY_ARG2, - .help = "SETNAME ENTRY\n" - " Delete entry from the named set", - }, - { /* t[est], --test, -T */ - .cmd = IPSET_CMD_TEST, - .name = { "test", NULL }, - .has_arg = IPSET_MANDATORY_ARG2, - .help = "SETNAME ENTRY\n" - " Test entry in the named set", - }, - { /* des[troy], --destroy, x, -X */ - .cmd = IPSET_CMD_DESTROY, - .name = { "destroy", "x" }, - .has_arg = IPSET_OPTIONAL_ARG, - .help = "[SETNAME]\n" - " Destroy a named set or all sets", - }, - { /* l[ist], --list, -L */ - .cmd = IPSET_CMD_LIST, - .name = { "list", NULL }, - .has_arg = IPSET_OPTIONAL_ARG, - .help = "[SETNAME]\n" - " List the entries of a named set or all sets", - }, - { /* s[save], --save, -S */ - .cmd = IPSET_CMD_SAVE, - .name = { "save", NULL }, - .has_arg = IPSET_OPTIONAL_ARG, - .help = "[SETNAME]\n" - " Save the named set or all sets to stdout", - }, - { /* r[estore], --restore, -R */ - .cmd = IPSET_CMD_RESTORE, - .name = { "restore", NULL }, - .has_arg = IPSET_NO_ARG, - .help = "\n" - " Restore a saved state", - }, - { /* f[lush], --flush, -F */ - .cmd = IPSET_CMD_FLUSH, - .name = { "flush", NULL }, - .has_arg = IPSET_OPTIONAL_ARG, - .help = "[SETNAME]\n" - " Flush a named set or all sets", - }, - { /* ren[ame], --rename, e, -E */ - .cmd = IPSET_CMD_RENAME, - .name = { "rename", "e" }, - .has_arg = IPSET_MANDATORY_ARG2, - .help = "FROM-SETNAME TO-SETNAME\n" - " Rename two sets", - }, - { /* sw[ap], --swap, w, -W */ - .cmd = IPSET_CMD_SWAP, - .name = { "swap", "w" }, - .has_arg = IPSET_MANDATORY_ARG2, - .help = "FROM-SETNAME TO-SETNAME\n" - " Swap the contect of two existing sets", - }, - { /* h[elp, --help, -H */ - .cmd = IPSET_CMD_HELP, - .name = { "help", NULL }, - .has_arg = IPSET_OPTIONAL_ARG, - .help = "[TYPENAME]\n" - " Print help, and settype specific help", - }, - { /* v[ersion], --version, -V */ - .cmd = IPSET_CMD_VERSION, - .name = { "version", NULL }, - .has_arg = IPSET_NO_ARG, - .help = "\n" - " Print version information", - }, - { /* q[uit] */ - .cmd = IPSET_CMD_QUIT, - .name = { "quit", NULL }, - .has_arg = IPSET_NO_ARG, - .help = "\n" - " Quit interactive mode", - }, - { }, -}; - -/* Match a command: try to match as a prefix or letter-command */ -bool -ipset_match_cmd(const char *arg, const char * const name[]) -{ - size_t len; - - assert(arg); - assert(name && name[0]); - - /* Ignore (two) leading dashes */ - if (arg[0] == '-') - arg++; - if (arg[0] == '-') - arg++; - - len = strlen(arg); - - if (len > strlen(name[0]) || !len) - return false; - else if (len > 1 && - ((strncmp(arg, name[0], len) == 0) || - (name[1] != NULL && (strncmp(arg, name[1], len) == 0)))) - return true; - else if (len != 1) - return false; - else - return tolower(arg[0]) == name[0][0] || - (name[1] != NULL && tolower(arg[0]) == name[1][0]); -} - -const struct ipset_envopts ipset_envopts[] = { - { .name = { "-o", "-output" }, - .has_arg = IPSET_MANDATORY_ARG, .flag = IPSET_OPT_MAX, - .parse = ipset_parse_output, - .help = "plain|save|xml\n" - " Specify output mode for listing sets.\n" - " Default value for \"list\" command is mode \"plain\"\n" - " and for \"save\" command is mode \"save\".", - }, - { .name = { "-s", "-sorted" }, - .parse = ipset_envopt_parse, - .has_arg = IPSET_NO_ARG, .flag = IPSET_ENV_SORTED, - .help = "\n" - " Print elements sorted (if supported by the set type).", - }, - { .name = { "-q", "-quiet" }, - .parse = ipset_envopt_parse, - .has_arg = IPSET_NO_ARG, .flag = IPSET_ENV_QUIET, - .help = "\n" - " Suppress any notice or warning message.", - }, - { .name = { "-r", "-resolve" }, - .parse = ipset_envopt_parse, - .has_arg = IPSET_NO_ARG, .flag = IPSET_ENV_RESOLVE, - .help = "\n" - " Try to resolve IP addresses in the output (slow!)", - }, - { .name = { "-!", "-exist" }, - .parse = ipset_envopt_parse, - .has_arg = IPSET_NO_ARG, .flag = IPSET_ENV_EXIST, - .help = "\n" - " Ignore errors when creating already created sets,\n" - " when adding already existing elements\n" - " or when deleting non-existing elements.", - }, - { .name = { "-n", "-name" }, - .parse = ipset_envopt_parse, - .has_arg = IPSET_NO_ARG, .flag = IPSET_ENV_LIST_SETNAME, - .help = "\n" - " When listing, list just setnames from kernel.\n", - }, - { .name = { "-t", "-terse" }, - .parse = ipset_envopt_parse, - .has_arg = IPSET_NO_ARG, .flag = IPSET_ENV_LIST_HEADER, - .help = "\n" - " When listing, list setnames and set headers\n" - " from kernel only.", - }, - { }, -}; - -/* Strict option matching */ -bool -ipset_match_option(const char *arg, const char * const name[]) -{ - assert(arg); - assert(name && name[0]); - - /* Skip two leading dashes */ - if (arg[0] == '-' && arg[1] == '-') - arg++, arg++; - - return STREQ(arg, name[0]) || - (name[1] != NULL && STREQ(arg, name[1])); -} - -/* Strict envopt matching */ -bool -ipset_match_envopt(const char *arg, const char * const name[]) -{ - assert(arg); - assert(name && name[0]); - - /* Skip one leading dash */ - if (arg[0] == '-' && arg[1] == '-') - arg++; - - return STREQ(arg, name[0]) || - (name[1] != NULL && STREQ(arg, name[1])); -} - -/** - * ipset_shift_argv - shift off an argument - * @arc: argument count - * @argv: array of argument strings - * @from: from where shift off an argument - * - * Shift off the argument at "from" from the array of - * arguments argv of size argc. - */ -void -ipset_shift_argv(int *argc, char *argv[], int from) -{ - int i; - - assert(*argc >= from + 1); - - for (i = from + 1; i <= *argc; i++) - argv[i-1] = argv[i]; - (*argc)--; - return; -} - -/** - * ipset_port_usage - prints the usage for the port parameter - * - * Print the usage for the port parameter to stdout. - */ -void -ipset_port_usage(void) -{ - int i; - const char *name; - - printf(" [PROTO:]PORT is a valid pattern of the following:\n" - " PORTNAME TCP port name from /etc/services\n" - " PORTNUMBER TCP port number identifier\n" - " tcp|sctp|udp|udplite:PORTNAME|PORTNUMBER\n" - " icmp:CODENAME supported ICMP codename\n" - " icmp:TYPE/CODE ICMP type/code value\n" - " icmpv6:CODENAME supported ICMPv6 codename\n" - " icmpv6:TYPE/CODE ICMPv6 type/code value\n" - " PROTO:0 all other protocols\n\n"); - - printf(" Supported ICMP codenames:\n"); - i = 0; - while ((name = id_to_icmp(i++)) != NULL) - printf(" %s\n", name); - printf(" Supported ICMPv6 codenames:\n"); - i = 0; - while ((name = id_to_icmpv6(i++)) != NULL) - printf(" %s\n", name); -} diff --git a/extensions/ipset-6/xt_set.c b/extensions/ipset-6/xt_set.c deleted file mode 100644 index 92789cb..0000000 --- a/extensions/ipset-6/xt_set.c +++ /dev/null @@ -1,422 +0,0 @@ -/* Copyright (C) 2000-2002 Joakim Axelsson - * Patrick Schaaf - * Martin Josefsson - * Copyright (C) 2003-2011 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Kernel module which implements the set match and SET target - * for netfilter/iptables. */ - -#include -#include - -#include -#include "xt_set.h" - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("Xtables: IP set match and target module"); -MODULE_ALIAS("xt_SET"); -MODULE_ALIAS("ipt_set"); -MODULE_ALIAS("ip6t_set"); -MODULE_ALIAS("ipt_SET"); -MODULE_ALIAS("ip6t_SET"); - -static inline int -match_set(ip_set_id_t index, const struct sk_buff *skb, - const struct xt_action_param *par, - const struct ip_set_adt_opt *opt, int inv) -{ - if (ip_set_test(index, skb, par, opt)) - inv = !inv; - return inv; -} - -#define ADT_OPT(n, f, d, fs, cfs, t) \ -const struct ip_set_adt_opt n = { \ - .family = f, \ - .dim = d, \ - .flags = fs, \ - .cmdflags = cfs, \ - .timeout = t, \ -} - -/* Revision 0 interface: backward compatible with netfilter/iptables */ - -static bool -set_match_v0(const struct sk_buff *skb, struct xt_action_param *par) -{ - const struct xt_set_info_match_v0 *info = par->matchinfo; - ADT_OPT(opt, par->family, info->match_set.u.compat.dim, - info->match_set.u.compat.flags, 0, UINT_MAX); - - return match_set(info->match_set.index, skb, par, &opt, - info->match_set.u.compat.flags & IPSET_INV_MATCH); -} - -static void -compat_flags(struct xt_set_info_v0 *info) -{ - u_int8_t i; - - /* Fill out compatibility data according to enum ip_set_kopt */ - info->u.compat.dim = IPSET_DIM_ZERO; - if (info->u.flags[0] & IPSET_MATCH_INV) - info->u.compat.flags |= IPSET_INV_MATCH; - for (i = 0; i < IPSET_DIM_MAX-1 && info->u.flags[i]; i++) { - info->u.compat.dim++; - if (info->u.flags[i] & IPSET_SRC) - info->u.compat.flags |= (1<u.compat.dim); - } -} - -static int -set_match_v0_checkentry(const struct xt_mtchk_param *par) -{ - struct xt_set_info_match_v0 *info = par->matchinfo; - ip_set_id_t index; - - index = ip_set_nfnl_get_byindex(info->match_set.index); - - if (index == IPSET_INVALID_ID) { - pr_warning("Cannot find set indentified by id %u to match\n", - info->match_set.index); - return -ENOENT; - } - if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) { - pr_warning("Protocol error: set match dimension " - "is over the limit!\n"); - ip_set_nfnl_put(info->match_set.index); - return -ERANGE; - } - - /* Fill out compatibility data */ - compat_flags(&info->match_set); - - return 0; -} - -static void -set_match_v0_destroy(const struct xt_mtdtor_param *par) -{ - struct xt_set_info_match_v0 *info = par->matchinfo; - - ip_set_nfnl_put(info->match_set.index); -} - -static unsigned int -set_target_v0(struct sk_buff *skb, const struct xt_action_param *par) -{ - const struct xt_set_info_target_v0 *info = par->targinfo; - ADT_OPT(add_opt, par->family, info->add_set.u.compat.dim, - info->add_set.u.compat.flags, 0, UINT_MAX); - ADT_OPT(del_opt, par->family, info->del_set.u.compat.dim, - info->del_set.u.compat.flags, 0, UINT_MAX); - - if (info->add_set.index != IPSET_INVALID_ID) - ip_set_add(info->add_set.index, skb, par, &add_opt); - if (info->del_set.index != IPSET_INVALID_ID) - ip_set_del(info->del_set.index, skb, par, &del_opt); - - return XT_CONTINUE; -} - -static int -set_target_v0_checkentry(const struct xt_tgchk_param *par) -{ - struct xt_set_info_target_v0 *info = par->targinfo; - ip_set_id_t index; - - if (info->add_set.index != IPSET_INVALID_ID) { - index = ip_set_nfnl_get_byindex(info->add_set.index); - if (index == IPSET_INVALID_ID) { - pr_warning("Cannot find add_set index %u as target\n", - info->add_set.index); - return -ENOENT; - } - } - - if (info->del_set.index != IPSET_INVALID_ID) { - index = ip_set_nfnl_get_byindex(info->del_set.index); - if (index == IPSET_INVALID_ID) { - pr_warning("Cannot find del_set index %u as target\n", - info->del_set.index); - if (info->add_set.index != IPSET_INVALID_ID) - ip_set_nfnl_put(info->add_set.index); - return -ENOENT; - } - } - if (info->add_set.u.flags[IPSET_DIM_MAX-1] != 0 || - info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) { - pr_warning("Protocol error: SET target dimension " - "is over the limit!\n"); - if (info->add_set.index != IPSET_INVALID_ID) - ip_set_nfnl_put(info->add_set.index); - if (info->del_set.index != IPSET_INVALID_ID) - ip_set_nfnl_put(info->del_set.index); - return -ERANGE; - } - - /* Fill out compatibility data */ - compat_flags(&info->add_set); - compat_flags(&info->del_set); - - return 0; -} - -static void -set_target_v0_destroy(const struct xt_tgdtor_param *par) -{ - const struct xt_set_info_target_v0 *info = par->targinfo; - - if (info->add_set.index != IPSET_INVALID_ID) - ip_set_nfnl_put(info->add_set.index); - if (info->del_set.index != IPSET_INVALID_ID) - ip_set_nfnl_put(info->del_set.index); -} - -/* Revision 1 match and target */ - -static bool -set_match_v1(const struct sk_buff *skb, struct xt_action_param *par) -{ - const struct xt_set_info_match_v1 *info = par->matchinfo; - ADT_OPT(opt, par->family, info->match_set.dim, - info->match_set.flags, 0, UINT_MAX); - - return match_set(info->match_set.index, skb, par, &opt, - info->match_set.flags & IPSET_INV_MATCH); -} - -static int -set_match_v1_checkentry(const struct xt_mtchk_param *par) -{ - struct xt_set_info_match_v1 *info = par->matchinfo; - ip_set_id_t index; - - index = ip_set_nfnl_get_byindex(info->match_set.index); - - if (index == IPSET_INVALID_ID) { - pr_warning("Cannot find set indentified by id %u to match\n", - info->match_set.index); - return -ENOENT; - } - if (info->match_set.dim > IPSET_DIM_MAX) { - pr_warning("Protocol error: set match dimension " - "is over the limit!\n"); - ip_set_nfnl_put(info->match_set.index); - return -ERANGE; - } - - return 0; -} - -static void -set_match_v1_destroy(const struct xt_mtdtor_param *par) -{ - struct xt_set_info_match_v1 *info = par->matchinfo; - - ip_set_nfnl_put(info->match_set.index); -} - -static unsigned int -set_target_v1(struct sk_buff *skb, const struct xt_action_param *par) -{ - const struct xt_set_info_target_v1 *info = par->targinfo; - ADT_OPT(add_opt, par->family, info->add_set.dim, - info->add_set.flags, 0, UINT_MAX); - ADT_OPT(del_opt, par->family, info->del_set.dim, - info->del_set.flags, 0, UINT_MAX); - - if (info->add_set.index != IPSET_INVALID_ID) - ip_set_add(info->add_set.index, skb, par, &add_opt); - if (info->del_set.index != IPSET_INVALID_ID) - ip_set_del(info->del_set.index, skb, par, &del_opt); - - return XT_CONTINUE; -} - -static int -set_target_v1_checkentry(const struct xt_tgchk_param *par) -{ - const struct xt_set_info_target_v1 *info = par->targinfo; - ip_set_id_t index; - - if (info->add_set.index != IPSET_INVALID_ID) { - index = ip_set_nfnl_get_byindex(info->add_set.index); - if (index == IPSET_INVALID_ID) { - pr_warning("Cannot find add_set index %u as target\n", - info->add_set.index); - return -ENOENT; - } - } - - if (info->del_set.index != IPSET_INVALID_ID) { - index = ip_set_nfnl_get_byindex(info->del_set.index); - if (index == IPSET_INVALID_ID) { - pr_warning("Cannot find del_set index %u as target\n", - info->del_set.index); - if (info->add_set.index != IPSET_INVALID_ID) - ip_set_nfnl_put(info->add_set.index); - return -ENOENT; - } - } - if (info->add_set.dim > IPSET_DIM_MAX || - info->del_set.dim > IPSET_DIM_MAX) { - pr_warning("Protocol error: SET target dimension " - "is over the limit!\n"); - if (info->add_set.index != IPSET_INVALID_ID) - ip_set_nfnl_put(info->add_set.index); - if (info->del_set.index != IPSET_INVALID_ID) - ip_set_nfnl_put(info->del_set.index); - return -ERANGE; - } - - return 0; -} - -static void -set_target_v1_destroy(const struct xt_tgdtor_param *par) -{ - const struct xt_set_info_target_v1 *info = par->targinfo; - - if (info->add_set.index != IPSET_INVALID_ID) - ip_set_nfnl_put(info->add_set.index); - if (info->del_set.index != IPSET_INVALID_ID) - ip_set_nfnl_put(info->del_set.index); -} - -/* Revision 2 target */ - -static unsigned int -set_target_v2(struct sk_buff *skb, const struct xt_action_param *par) -{ - const struct xt_set_info_target_v2 *info = par->targinfo; - ADT_OPT(add_opt, par->family, info->add_set.dim, - info->add_set.flags, info->flags, info->timeout); - ADT_OPT(del_opt, par->family, info->del_set.dim, - info->del_set.flags, 0, UINT_MAX); - - if (info->add_set.index != IPSET_INVALID_ID) - ip_set_add(info->add_set.index, skb, par, &add_opt); - if (info->del_set.index != IPSET_INVALID_ID) - ip_set_del(info->del_set.index, skb, par, &del_opt); - - return XT_CONTINUE; -} - -#define set_target_v2_checkentry set_target_v1_checkentry -#define set_target_v2_destroy set_target_v1_destroy - -static struct xt_match set_matches[] __read_mostly = { - { - .name = "set", - .family = NFPROTO_IPV4, - .revision = 0, - .match = set_match_v0, - .matchsize = sizeof(struct xt_set_info_match_v0), - .checkentry = set_match_v0_checkentry, - .destroy = set_match_v0_destroy, - .me = THIS_MODULE - }, - { - .name = "set", - .family = NFPROTO_IPV4, - .revision = 1, - .match = set_match_v1, - .matchsize = sizeof(struct xt_set_info_match_v1), - .checkentry = set_match_v1_checkentry, - .destroy = set_match_v1_destroy, - .me = THIS_MODULE - }, - { - .name = "set", - .family = NFPROTO_IPV6, - .revision = 1, - .match = set_match_v1, - .matchsize = sizeof(struct xt_set_info_match_v1), - .checkentry = set_match_v1_checkentry, - .destroy = set_match_v1_destroy, - .me = THIS_MODULE - }, -}; - -static struct xt_target set_targets[] __read_mostly = { - { - .name = "SET", - .revision = 0, - .family = NFPROTO_IPV4, - .target = set_target_v0, - .targetsize = sizeof(struct xt_set_info_target_v0), - .checkentry = set_target_v0_checkentry, - .destroy = set_target_v0_destroy, - .me = THIS_MODULE - }, - { - .name = "SET", - .revision = 1, - .family = NFPROTO_IPV4, - .target = set_target_v1, - .targetsize = sizeof(struct xt_set_info_target_v1), - .checkentry = set_target_v1_checkentry, - .destroy = set_target_v1_destroy, - .me = THIS_MODULE - }, - { - .name = "SET", - .revision = 1, - .family = NFPROTO_IPV6, - .target = set_target_v1, - .targetsize = sizeof(struct xt_set_info_target_v1), - .checkentry = set_target_v1_checkentry, - .destroy = set_target_v1_destroy, - .me = THIS_MODULE - }, - { - .name = "SET", - .revision = 2, - .family = NFPROTO_IPV4, - .target = set_target_v2, - .targetsize = sizeof(struct xt_set_info_target_v2), - .checkentry = set_target_v2_checkentry, - .destroy = set_target_v2_destroy, - .me = THIS_MODULE - }, - { - .name = "SET", - .revision = 2, - .family = NFPROTO_IPV6, - .target = set_target_v2, - .targetsize = sizeof(struct xt_set_info_target_v2), - .checkentry = set_target_v2_checkentry, - .destroy = set_target_v2_destroy, - .me = THIS_MODULE - }, -}; - -static int __init xt_set_init(void) -{ - int ret = xt_register_matches(set_matches, ARRAY_SIZE(set_matches)); - - if (!ret) { - ret = xt_register_targets(set_targets, - ARRAY_SIZE(set_targets)); - if (ret) - xt_unregister_matches(set_matches, - ARRAY_SIZE(set_matches)); - } - return ret; -} - -static void __exit xt_set_fini(void) -{ - xt_unregister_matches(set_matches, ARRAY_SIZE(set_matches)); - xt_unregister_targets(set_targets, ARRAY_SIZE(set_targets)); -} - -module_init(xt_set_init); -module_exit(xt_set_fini); diff --git a/extensions/ipset-6/xt_set.h b/extensions/ipset-6/xt_set.h deleted file mode 100644 index a84ac05..0000000 --- a/extensions/ipset-6/xt_set.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _XT_SET_H -#define _XT_SET_H - -#include -#include "ip_set.h" - -/* Revision 0 interface: backward compatible with netfilter/iptables */ - -/* - * Option flags for kernel operations (xt_set_info_v0) - */ -#define IPSET_SRC 0x01 /* Source match/add */ -#define IPSET_DST 0x02 /* Destination match/add */ -#define IPSET_MATCH_INV 0x04 /* Inverse matching */ - -struct xt_set_info_v0 { - ip_set_id_t index; - union { - __u32 flags[IPSET_DIM_MAX + 1]; - struct { - __u32 __flags[IPSET_DIM_MAX]; - __u8 dim; - __u8 flags; - } compat; - } u; -}; - -/* match and target infos */ -struct xt_set_info_match_v0 { - struct xt_set_info_v0 match_set; -}; - -struct xt_set_info_target_v0 { - struct xt_set_info_v0 add_set; - struct xt_set_info_v0 del_set; -}; - -/* Revision 1 match and target */ - -struct xt_set_info { - ip_set_id_t index; - __u8 dim; - __u8 flags; -}; - -/* match and target infos */ -struct xt_set_info_match_v1 { - struct xt_set_info match_set; -}; - -struct xt_set_info_target_v1 { - struct xt_set_info add_set; - struct xt_set_info del_set; -}; - -/* Revision 2 target */ - -struct xt_set_info_target_v2 { - struct xt_set_info add_set; - struct xt_set_info del_set; - __u32 flags; - __u32 timeout; -}; - -#endif /*_XT_SET_H*/ diff --git a/mconfig b/mconfig index 62da806..4fc664a 100644 --- a/mconfig +++ b/mconfig @@ -20,7 +20,6 @@ build_geoip=m build_gradm=m build_iface=m build_ipp2p=m -build_ipset6= build_ipv4options=m build_length2=m build_lscan=m