* published by the Free Software Foundation.
*/
+#include <linux/types.h>
+
/* The protocol version */
#define IPSET_PROTOCOL 6
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 */
* - AF_INET46: type supports both IPv4 and IPv6
*/
-/* Set dimensions */
-enum {
- IPSET_DIM_ONE, /* foo */
- IPSET_DIM_TWO, /* foo,bar */
- IPSET_DIM_THREE, /* foo,bar,fie */
- IPSET_DIM_MAX,
-};
+/* The maximal type dimension userspace supports */
+#define IPSET_DIM_UMAX 3
/* Parser options */
enum {
uint8_t dimension; /* elem dimension */
int8_t kernel_check; /* kernel check */
bool last_elem_optional; /* last element optional */
- struct ipset_elem elem[IPSET_DIM_MAX]; /* parse elem */
+ 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 */
#define parse_elem(s, t, d, str) \
do { \
- if (!(t)->elem[d].parse) \
+ if (!(t)->elem[d - 1].parse) \
goto internal; \
- ret = (t)->elem[d].parse(s, (t)->elem[d].opt, str); \
+ ret = (t)->elem[d - 1].parse(s, (t)->elem[d - 1].opt, str); \
if (ret) \
goto out; \
} while (0)
} else if (a != NULL) {
if (type->compat_parse_elem) {
ret = type->compat_parse_elem(session,
- type->elem[IPSET_DIM_ONE].opt,
+ type->elem[IPSET_DIM_ONE - 1].opt,
saved);
goto out;
}
if (!type)
return -1;
- size = type->elem[IPSET_DIM_ONE].print(buf, len, data,
- type->elem[IPSET_DIM_ONE].opt, env);
+ 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].opt),
+ 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].opt)))
+ !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].print(buf + offset, len, data,
- type->elem[IPSET_DIM_TWO].opt, env);
+ 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].opt)))
+ !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].print(buf + offset, len, data,
- type->elem[IPSET_DIM_THREE].opt, env);
+ 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;
.family = AF_INET,
.dimension = IPSET_DIM_ONE,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_ip,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
.dimension = IPSET_DIM_TWO,
.last_elem_optional = true,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_single_ip,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
},
- [IPSET_DIM_TWO] = {
+ [IPSET_DIM_TWO - 1] = {
.parse = ipset_parse_ether,
.print = ipset_print_ether,
.opt = IPSET_OPT_ETHER
.family = AF_UNSPEC,
.dimension = IPSET_DIM_ONE,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_tcp_port,
.print = ipset_print_port,
.opt = IPSET_OPT_PORT
.family = AF_INET46,
.dimension = IPSET_DIM_ONE,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_ip4_single6,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
.family = AF_INET46,
.dimension = IPSET_DIM_TWO,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_ip4_single6,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
},
- [IPSET_DIM_TWO] = {
+ [IPSET_DIM_TWO - 1] = {
.parse = ipset_parse_proto_port,
.print = ipset_print_proto_port,
.opt = IPSET_OPT_PORT
.family = AF_INET46,
.dimension = IPSET_DIM_THREE,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_ip4_single6,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
},
- [IPSET_DIM_TWO] = {
+ [IPSET_DIM_TWO - 1] = {
.parse = ipset_parse_proto_port,
.print = ipset_print_proto_port,
.opt = IPSET_OPT_PORT
},
- [IPSET_DIM_THREE] = {
+ [IPSET_DIM_THREE - 1] = {
.parse = ipset_parse_single_ip,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP2
.family = AF_INET46,
.dimension = IPSET_DIM_THREE,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_ip4_single6,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
},
- [IPSET_DIM_TWO] = {
+ [IPSET_DIM_TWO - 1] = {
.parse = ipset_parse_proto_port,
.print = ipset_print_proto_port,
.opt = IPSET_OPT_PORT
},
- [IPSET_DIM_THREE] = {
+ [IPSET_DIM_THREE - 1] = {
.parse = ipset_parse_ipnet,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP2
.family = AF_INET46,
.dimension = IPSET_DIM_THREE,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_ip4_single6,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
},
- [IPSET_DIM_TWO] = {
+ [IPSET_DIM_TWO - 1] = {
.parse = ipset_parse_proto_port,
.print = ipset_print_proto_port,
.opt = IPSET_OPT_PORT
},
- [IPSET_DIM_THREE] = {
+ [IPSET_DIM_THREE - 1] = {
.parse = ipset_parse_ip4_net6,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP2
.family = AF_INET46,
.dimension = IPSET_DIM_ONE,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_ipnet,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
.family = AF_INET46,
.dimension = IPSET_DIM_ONE,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_ip4_net6,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
.family = AF_INET46,
.dimension = IPSET_DIM_TWO,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_ip4_net6,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
},
- [IPSET_DIM_TWO] = {
+ [IPSET_DIM_TWO - 1] = {
.parse = ipset_parse_iface,
.print = ipset_print_iface,
.opt = IPSET_OPT_IFACE
.family = AF_INET46,
.dimension = IPSET_DIM_TWO,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_ipnet,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
},
- [IPSET_DIM_TWO] = {
+ [IPSET_DIM_TWO - 1] = {
.parse = ipset_parse_proto_port,
.print = ipset_print_proto_port,
.opt = IPSET_OPT_PORT
.family = AF_INET46,
.dimension = IPSET_DIM_TWO,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_ip4_net6,
.print = ipset_print_ip,
.opt = IPSET_OPT_IP
},
- [IPSET_DIM_TWO] = {
+ [IPSET_DIM_TWO - 1] = {
.parse = ipset_parse_proto_port,
.print = ipset_print_proto_port,
.opt = IPSET_OPT_PORT
.family = AF_UNSPEC,
.dimension = IPSET_DIM_ONE,
.elem = {
- [IPSET_DIM_ONE] = {
+ [IPSET_DIM_ONE - 1] = {
.parse = ipset_parse_setname,
.print = ipset_print_name,
.opt = IPSET_OPT_NAME