From d40f1628c3717daebc437a398a285e371b5b6f7f Mon Sep 17 00:00:00 2001
From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Date: Wed, 16 Jun 2010 12:45:33 +0200
Subject: [PATCH] libxt_set: new revision added
Patch-mainline: v1.4.9
Git-commit: d40f1628c3717daebc437a398a285e371b5b6f7f
References: bnc#868452

libipt_set renamed to libxt_set and the support for the forthcoming
ipset release added. I have tested backward (IPv4) and forward
compatibility (IPv4/IPv6):

ipset -N test iphash
ipset -A test test-address
iptables -N test-set
iptables -A test-set -j LOG --log-prefix "match "
iptables -A test-set -j DROP
iptables -A OUTPUT -m set --match-set test dst -j test-set
ping test-address
---
 extensions/libipt_SET.c                | 164 -----------
 extensions/libipt_SET.man              |  18 --
 extensions/libipt_set.c                | 160 -----------
 extensions/libipt_set.h                | 119 --------
 extensions/libipt_set.man              |  23 --
 extensions/libxt_SET.c                 | 286 +++++++++++++++++++
 extensions/libxt_SET.man               |  18 ++
 extensions/libxt_set.c                 | 250 +++++++++++++++++
 extensions/libxt_set.h                 | 147 ++++++++++
 extensions/libxt_set.man               |  23 ++
 include/linux/netfilter/xt_set.h       | 110 ++++++++
 include/linux/netfilter_ipv4/ip_set.h  | 498 ---------------------------------
 include/linux/netfilter_ipv4/ipt_set.h |  21 --
 13 files changed, 834 insertions(+), 1003 deletions(-)
 delete mode 100644 extensions/libipt_SET.c
 delete mode 100644 extensions/libipt_SET.man
 delete mode 100644 extensions/libipt_set.c
 delete mode 100644 extensions/libipt_set.h
 delete mode 100644 extensions/libipt_set.man
 create mode 100644 extensions/libxt_SET.c
 create mode 100644 extensions/libxt_SET.man
 create mode 100644 extensions/libxt_set.c
 create mode 100644 extensions/libxt_set.h
 create mode 100644 extensions/libxt_set.man
 create mode 100644 include/linux/netfilter/xt_set.h
 delete mode 100644 include/linux/netfilter_ipv4/ip_set.h
 delete mode 100644 include/linux/netfilter_ipv4/ipt_set.h

diff --git a/extensions/libipt_SET.c b/extensions/libipt_SET.c
deleted file mode 100644
index 18cf7d4..0000000
--- a/extensions/libipt_SET.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
- *                         Patrick Schaaf <bof@bof.de>
- *                         Martin Josefsson <gandalf@wlug.westbo.se>
- * Copyright (C) 2003-2004 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.  
- */
-
-/* Shared library add-on to iptables to add IP set mangling target. */
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <ctype.h>
-
-#include <xtables.h>
-#include <linux/netfilter_ipv4/ip_set.h>
-#include <linux/netfilter_ipv4/ipt_set.h>
-#include "libipt_set.h"
-
-static void SET_help(void)
-{
-	printf("SET target options:\n"
-	       " --add-set name flags\n"
-	       " --del-set name flags\n"
-	       "		add/del src/dst IP/port from/to named sets,\n"
-	       "		where flags are the comma separated list of\n"
-	       "		'src' and 'dst' specifications.\n");
-}
-
-static const struct option SET_opts[] = {
-	{ .name = "add-set", .has_arg = true, .val = '1'},
-	{ .name = "del-set", .has_arg = true, .val = '2'},
-	{ .name = NULL }
-};
-
-static void SET_init(struct xt_entry_target *target)
-{
-	struct ipt_set_info_target *info =
-	    (struct ipt_set_info_target *) target->data;
-
-	memset(info, 0, sizeof(struct ipt_set_info_target));
-	info->add_set.index =
-	info->del_set.index = IP_SET_INVALID_ID;
-
-}
-
-static void
-parse_target(char **argv, int invert, unsigned int *flags,
-             struct ipt_set_info *info, const char *what)
-{
-	if (info->flags[0])
-		xtables_error(PARAMETER_PROBLEM,
-			   "--%s can be specified only once", what);
-
-	if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
-		xtables_error(PARAMETER_PROBLEM,
-			   "Unexpected `!' after --%s", what);
-
-	if (!argv[optind]
-	    || argv[optind][0] == '-' || argv[optind][0] == '!')
-		xtables_error(PARAMETER_PROBLEM,
-			   "--%s requires two args.", what);
-
-	if (strlen(optarg) > IP_SET_MAXNAMELEN - 1)
-		xtables_error(PARAMETER_PROBLEM,
-			   "setname `%s' too long, max %d characters.",
-			   optarg, IP_SET_MAXNAMELEN - 1);
-
-	get_set_byname(optarg, info);
-	parse_bindings(argv[optind], info);
-	optind++;
-	
-	*flags = 1;
-}
-
-static int SET_parse(int c, char **argv, int invert, unsigned int *flags,
-                     const void *entry, struct xt_entry_target **target)
-{
-	struct ipt_set_info_target *myinfo =
-	    (struct ipt_set_info_target *) (*target)->data;
-
-	switch (c) {
-	case '1':		/* --add-set <set> <flags> */
-		parse_target(argv, invert, flags,
-			     &myinfo->add_set, "add-set");
-		break;
-	case '2':		/* --del-set <set>[:<flags>] <flags> */
-		parse_target(argv, invert, flags,
-			     &myinfo->del_set, "del-set");
-		break;
-
-	default:
-		return 0;
-	}
-	return 1;
-}
-
-static void SET_check(unsigned int flags)
-{
-	if (!flags)
-		xtables_error(PARAMETER_PROBLEM,
-			   "You must specify either `--add-set' or `--del-set'");
-}
-
-static void
-print_target(const char *prefix, const struct ipt_set_info *info)
-{
-	int i;
-	char setname[IP_SET_MAXNAMELEN];
-
-	if (info->index == IP_SET_INVALID_ID)
-		return;
-	get_set_byid(setname, info->index);
-	printf("%s %s", prefix, setname);
-	for (i = 0; i < IP_SET_MAX_BINDINGS; i++) {
-		if (!info->flags[i])
-			break;		
-		printf("%s%s",
-		       i == 0 ? " " : ",",
-		       info->flags[i] & IPSET_SRC ? "src" : "dst");
-	}
-	printf(" ");
-}
-
-static void SET_print(const void *ip, const struct xt_entry_target *target,
-                      int numeric)
-{
-	const struct ipt_set_info_target *info = (const void *)target->data;
-
-	print_target("add-set", &info->add_set);
-	print_target("del-set", &info->del_set);
-}
-
-static void SET_save(const void *ip, const struct xt_entry_target *target)
-{
-	const struct ipt_set_info_target *info = (const void *)target->data;
-
-	print_target("--add-set", &info->add_set);
-	print_target("--del-set", &info->del_set);
-}
-
-static struct xtables_target set_tg_reg = {
-	.name		= "SET",
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_IPV4,
-	.size		= XT_ALIGN(sizeof(struct ipt_set_info_target)),
-	.userspacesize	= XT_ALIGN(sizeof(struct ipt_set_info_target)),
-	.help		= SET_help,
-	.init		= SET_init,
-	.parse		= SET_parse,
-	.final_check	= SET_check,
-	.print		= SET_print,
-	.save		= SET_save,
-	.extra_opts	= SET_opts,
-};
-
-void _init(void)
-{
-	xtables_register_target(&set_tg_reg);
-}
diff --git a/extensions/libipt_SET.man b/extensions/libipt_SET.man
deleted file mode 100644
index ea80c2a..0000000
--- a/extensions/libipt_SET.man
+++ /dev/null
@@ -1,14 +0,0 @@
-This modules adds and/or deletes entries from IP sets which can be defined 
-by ipset(8).
-.TP
-\fB\-\-add\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP...]
-add the address(es)/port(s) of the packet to the sets
-.TP
-\fB\-\-del\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP...]
-delete the address(es)/port(s) of the packet from the sets
-.IP
-where flags are
-.BR "src"
-and/or
-.BR "dst"
-specifications and there can be no more than six of them.
diff --git a/extensions/libipt_set.c b/extensions/libipt_set.c
deleted file mode 100644
index 9f7a97c..0000000
--- a/extensions/libipt_set.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
- *                         Patrick Schaaf <bof@bof.de>
- *                         Martin Josefsson <gandalf@wlug.westbo.se>
- * Copyright (C) 2003-2004 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.  
- */
-
-/* Shared library add-on to iptables to add IP set matching. */
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <xtables.h>
-#include <linux/netfilter_ipv4/ipt_set.h>
-#include "libipt_set.h"
-
-static void set_help(void)
-{
-	printf("set match options:\n"
-	       " [!] --match-set name flags\n"
-	       "		 'name' is the set name from to match,\n" 
-	       "		 'flags' are the comma separated list of\n"
-	       "		 'src' and 'dst' specifications.\n");
-}
-
-static const struct option set_opts[] = {
-	{ .name = "match-set", .has_arg = true, .val = '1'},
-	{ .name = "set",       .has_arg = true, .val = '2'},
-	{ .name = NULL }
-};
-
-static void set_init(struct xt_entry_match *match)
-{
-	struct ipt_set_info_match *info = 
-		(struct ipt_set_info_match *) match->data;
-	
-
-	memset(info, 0, sizeof(struct ipt_set_info_match));
-
-}
-
-static int set_parse(int c, char **argv, int invert, unsigned int *flags,
-                     const void *entry, struct xt_entry_match **match)
-{
-	struct ipt_set_info_match *myinfo = 
-		(struct ipt_set_info_match *) (*match)->data;
-	struct ipt_set_info *info = &myinfo->match_set;
-
-	switch (c) {
-	case '2':
-#if 0
-		fprintf(stderr,
-			"--set option deprecated, please use --match-set\n");
-#endif
-	case '1':		/* --match-set <set> <flag>[,<flag> */
-		if (info->flags[0])
-			xtables_error(PARAMETER_PROBLEM,
-				   "--match-set can be specified only once");
-
-		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
-		if (invert)
-			info->flags[0] |= IPSET_MATCH_INV;
-
-		if (!argv[optind]
-		    || argv[optind][0] == '-'
-		    || argv[optind][0] == '!')
-			xtables_error(PARAMETER_PROBLEM,
-				   "--match-set requires two args.");
-
-		if (strlen(optarg) > IP_SET_MAXNAMELEN - 1)
-			xtables_error(PARAMETER_PROBLEM,
-				   "setname `%s' too long, max %d characters.",
-				   optarg, IP_SET_MAXNAMELEN - 1);
-
-		get_set_byname(optarg, info);
-		parse_bindings(argv[optind], info);
-		DEBUGP("parse: set index %u\n", info->index);
-		optind++;
-		
-		*flags = 1;
-		break;
-
-	default:
-		return 0;
-	}
-
-	return 1;
-}
-
-static void set_check(unsigned int flags)
-{
-	if (!flags)
-		xtables_error(PARAMETER_PROBLEM,
-			   "You must specify `--match-set' with proper arguments");
-	DEBUGP("final check OK\n");
-}
-
-static void
-print_match(const char *prefix, const struct ipt_set_info *info)
-{
-	int i;
-	char setname[IP_SET_MAXNAMELEN];
-
-	get_set_byid(setname, info->index);
-	printf("%s%s %s", 
-	       (info->flags[0] & IPSET_MATCH_INV) ? "! " : "",
-	       prefix,
-	       setname); 
-	for (i = 0; i < IP_SET_MAX_BINDINGS; i++) {
-		if (!info->flags[i])
-			break;		
-		printf("%s%s",
-		       i == 0 ? " " : ",",
-		       info->flags[i] & IPSET_SRC ? "src" : "dst");
-	}
-	printf(" ");
-}
-
-/* Prints out the matchinfo. */
-static void set_print(const void *ip, const struct xt_entry_match *match,
-                      int numeric)
-{
-	const struct ipt_set_info_match *info = (const void *)match->data;
-
-	print_match("match-set", &info->match_set);
-}
-
-static void set_save(const void *ip, const struct xt_entry_match *match)
-{
-	const struct ipt_set_info_match *info = (const void *)match->data;
-
-	print_match("--match-set", &info->match_set);
-}
-
-static struct xtables_match set_mt_reg = {
-	.name		= "set",
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_IPV4,
-	.size		= XT_ALIGN(sizeof(struct ipt_set_info_match)),
-	.userspacesize	= XT_ALIGN(sizeof(struct ipt_set_info_match)),
-	.help		= set_help,
-	.init		= set_init,
-	.parse		= set_parse,
-	.final_check	= set_check,
-	.print		= set_print,
-	.save		= set_save,
-	.extra_opts	= set_opts,
-};
-
-void _init(void)
-{
-	xtables_register_match(&set_mt_reg);
-}
diff --git a/extensions/libipt_set.h b/extensions/libipt_set.h
deleted file mode 100644
index 0e9b0b5..0000000
--- a/extensions/libipt_set.h
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifndef _LIBIPT_SET_H
-#define _LIBIPT_SET_H
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <errno.h>
-
-#ifdef DEBUG
-#define DEBUGP(x, args...) fprintf(stderr, x, ## args)
-#else
-#define DEBUGP(x, args...) 
-#endif
-
-static void
-parse_bindings(const char *opt_arg, struct ipt_set_info *info)
-{
-	char *saved = strdup(opt_arg);
-	char *ptr, *tmp = saved;
-	int i = 0;
-	
-	while (i < (IP_SET_MAX_BINDINGS - 1) && tmp != NULL) {
-		ptr = strsep(&tmp, ",");
-		if (strncmp(ptr, "src", 3) == 0)
-			info->flags[i++] |= IPSET_SRC;
-		else if (strncmp(ptr, "dst", 3) == 0)
-			info->flags[i++] |= IPSET_DST;
-		else
-			xtables_error(PARAMETER_PROBLEM,
-				   "You must spefify (the comma separated list of) 'src' or 'dst'.");
-	}
-
-	if (tmp)
-		xtables_error(PARAMETER_PROBLEM,
-			   "Can't follow bindings deeper than %i.", 
-			   IP_SET_MAX_BINDINGS - 1);
-
-	free(saved);
-}
-
-static int get_version(unsigned *version)
-{
-	int res, sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-	struct ip_set_req_version req_version;
-	socklen_t size = sizeof(req_version);
-	
-	if (sockfd < 0)
-		xtables_error(OTHER_PROBLEM,
-			   "Can't open socket to ipset.\n");
-
-	req_version.op = IP_SET_OP_VERSION;
-	res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size);
-	if (res != 0)
-		xtables_error(OTHER_PROBLEM,
-			   "Kernel module ip_set is not loaded in.\n");
-
-	*version = req_version.version;
-	
-	return sockfd;
-}
-
-static void get_set_byname(const char *setname, struct ipt_set_info *info)
-{
-	struct ip_set_req_get_set req;
-	socklen_t size = sizeof(struct ip_set_req_get_set);
-	int res, sockfd;
-
-	sockfd = get_version(&req.version);
-	req.op = IP_SET_OP_GET_BYNAME;
-	strncpy(req.set.name, setname, IP_SET_MAXNAMELEN);
-	req.set.name[IP_SET_MAXNAMELEN - 1] = '\0';
-	res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size);
-	close(sockfd);
-
-	if (res != 0)
-		xtables_error(OTHER_PROBLEM,
-			   "Problem when communicating with ipset, errno=%d.\n",
-			   errno);
-	if (size != sizeof(struct ip_set_req_get_set))
-		xtables_error(OTHER_PROBLEM,
-			   "Incorrect return size from kernel during ipset lookup, "
-			   "(want %zu, got %zu)\n",
-			   sizeof(struct ip_set_req_get_set), (size_t)size);
-	if (req.set.index == IP_SET_INVALID_ID)
-		xtables_error(PARAMETER_PROBLEM,
-			   "Set %s doesn't exist.\n", setname);
-
-	info->index = req.set.index;
-}
-
-static void get_set_byid(char * setname, ip_set_id_t idx)
-{
-	struct ip_set_req_get_set req;
-	socklen_t size = sizeof(struct ip_set_req_get_set);
-	int res, sockfd;
-
-	sockfd = get_version(&req.version);
-	req.op = IP_SET_OP_GET_BYINDEX;
-	req.set.index = idx;
-	res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size);
-	close(sockfd);
-
-	if (res != 0)
-		xtables_error(OTHER_PROBLEM,
-			   "Problem when communicating with ipset, errno=%d.\n",
-			   errno);
-	if (size != sizeof(struct ip_set_req_get_set))
-		xtables_error(OTHER_PROBLEM,
-			   "Incorrect return size from kernel during ipset lookup, "
-			   "(want %zu, got %zu)\n",
-			   sizeof(struct ip_set_req_get_set), (size_t)size);
-	if (req.set.name[0] == '\0')
-		xtables_error(PARAMETER_PROBLEM,
-			   "Set id %i in kernel doesn't exist.\n", idx);
-
-	strncpy(setname, req.set.name, IP_SET_MAXNAMELEN);
-}
-
-#endif /*_LIBIPT_SET_H*/
diff --git a/extensions/libipt_set.man b/extensions/libipt_set.man
deleted file mode 100644
index aca1bfc..0000000
--- a/extensions/libipt_set.man
+++ /dev/null
@@ -1,19 +0,0 @@
-This module matches IP sets which can be defined by ipset(8).
-.TP
-[\fB!\fP] \fB\-\-match\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP]...
-where flags are the comma separated list of
-.BR "src"
-and/or
-.BR "dst" 
-specifications and there can be no more than six of them. Hence the command
-.IP
- iptables \-A FORWARD \-m set \-\-match\-set test src,dst
-.IP
-will match packets, for which (if the set type is ipportmap) the source
-address and destination port pair can be found in the specified set. If
-the set type of the specified set is single dimension (for example ipmap),
-then the command will match packets for which the source address can be
-found in the specified set. 
-.PP
-The option \fB\-\-match\-set\fR can be replaced by \fB\-\-set\fR if that does 
-not clash with an option of other extensions.
diff --git a/extensions/libxt_SET.c b/extensions/libxt_SET.c
new file mode 100644
index 0000000..f6386a9
--- /dev/null
+++ b/extensions/libxt_SET.c
@@ -0,0 +1,286 @@
+/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
+ *                         Patrick Schaaf <bof@bof.de>
+ *                         Martin Josefsson <gandalf@wlug.westbo.se>
+ * Copyright (C) 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.  
+ */
+
+/* Shared library add-on to iptables to add IP set mangling target. */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <ctype.h>
+
+#include <xtables.h>
+#include <linux/netfilter/xt_set.h>
+#include "libxt_set.h"
+
+static void
+set_target_help(void)
+{
+	printf("SET target options:\n"
+	       " --add-set name flags\n"
+	       " --del-set name flags\n"
+	       "		add/del src/dst IP/port from/to named sets,\n"
+	       "		where flags are the comma separated list of\n"
+	       "		'src' and 'dst' specifications.\n");
+}
+
+static const struct option set_target_opts[] = {
+	{ .name = "add-set", .has_arg = true, .val = '1'},
+	{ .name = "del-set", .has_arg = true, .val = '2'},
+	{ .name = NULL }
+};
+
+static void
+set_target_check(unsigned int flags)
+{
+	if (!flags)
+		xtables_error(PARAMETER_PROBLEM,
+			   "You must specify either `--add-set' or `--del-set'");
+}
+
+static void
+set_target_init_v0(struct xt_entry_target *target)
+{
+	struct xt_set_info_target_v0 *info =
+		(struct xt_set_info_target_v0 *) target->data;
+
+	info->add_set.index =
+	info->del_set.index = IPSET_INVALID_ID;
+
+}
+
+static void
+parse_target_v0(char **argv, int invert, unsigned int *flags,
+		struct xt_set_info_v0 *info, const char *what)
+{
+	if (info->u.flags[0])
+		xtables_error(PARAMETER_PROBLEM,
+			      "--%s can be specified only once", what);
+
+	if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
+		xtables_error(PARAMETER_PROBLEM,
+			      "Unexpected `!' after --%s", what);
+
+	if (!argv[optind]
+	    || argv[optind][0] == '-' || argv[optind][0] == '!')
+		xtables_error(PARAMETER_PROBLEM,
+			      "--%s requires two args.", what);
+
+	if (strlen(optarg) > IPSET_MAXNAMELEN - 1)
+		xtables_error(PARAMETER_PROBLEM,
+			      "setname `%s' too long, max %d characters.",
+			      optarg, IPSET_MAXNAMELEN - 1);
+
+	get_set_byname(optarg, (struct xt_set_info *)info);
+	parse_dirs_v0(argv[optind], info);
+	optind++;
+	
+	*flags = 1;
+}
+
+static int
+set_target_parse_v0(int c, char **argv, int invert, unsigned int *flags,
+		    const void *entry, struct xt_entry_target **target)
+{
+	struct xt_set_info_target_v0 *myinfo =
+		(struct xt_set_info_target_v0 *) (*target)->data;
+
+	switch (c) {
+	case '1':		/* --add-set <set> <flags> */
+		parse_target_v0(argv, invert, flags,
+				&myinfo->add_set, "add-set");
+		break;
+	case '2':		/* --del-set <set>[:<flags>] <flags> */
+		parse_target_v0(argv, invert, flags,
+				&myinfo->del_set, "del-set");
+		break;
+
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+static void
+print_target_v0(const char *prefix, const struct xt_set_info_v0 *info)
+{
+	int i;
+	char setname[IPSET_MAXNAMELEN];
+
+	if (info->index == IPSET_INVALID_ID)
+		return;
+	get_set_byid(setname, info->index);
+	printf("%s %s", prefix, setname);
+	for (i = 0; i < IPSET_DIM_MAX; i++) {
+		if (!info->u.flags[i])
+			break;		
+		printf("%s%s",
+		       i == 0 ? " " : ",",
+		       info->u.flags[i] & IPSET_SRC ? "src" : "dst");
+	}
+	printf(" ");
+}
+
+static void
+set_target_print_v0(const void *ip, const struct xt_entry_target *target,
+                    int numeric)
+{
+	const struct xt_set_info_target_v0 *info = (const void *)target->data;
+
+	print_target_v0("add-set", &info->add_set);
+	print_target_v0("del-set", &info->del_set);
+}
+
+static void
+set_target_save_v0(const void *ip, const struct xt_entry_target *target)
+{
+	const struct xt_set_info_target_v0 *info = (const void *)target->data;
+
+	print_target_v0("--add-set", &info->add_set);
+	print_target_v0("--del-set", &info->del_set);
+}
+
+static void
+set_target_init(struct xt_entry_target *target)
+{
+	struct xt_set_info_target *info =
+		(struct xt_set_info_target *) target->data;
+
+	info->add_set.index =
+	info->del_set.index = IPSET_INVALID_ID;
+
+}
+
+static void
+parse_target(char **argv, int invert, unsigned int *flags,
+	     struct xt_set_info *info, const char *what)
+{
+	if (info->dim)
+		xtables_error(PARAMETER_PROBLEM,
+			      "--%s can be specified only once", what);
+
+	if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
+		xtables_error(PARAMETER_PROBLEM,
+			      "Unexpected `!' after --%s", what);
+
+	if (!argv[optind]
+	    || argv[optind][0] == '-' || argv[optind][0] == '!')
+		xtables_error(PARAMETER_PROBLEM,
+			      "--%s requires two args.", what);
+
+	if (strlen(optarg) > IPSET_MAXNAMELEN - 1)
+		xtables_error(PARAMETER_PROBLEM,
+			      "setname `%s' too long, max %d characters.",
+			      optarg, IPSET_MAXNAMELEN - 1);
+
+	get_set_byname(optarg, info);
+	parse_dirs(argv[optind], info);
+	optind++;
+	
+	*flags = 1;
+}
+
+static int
+set_target_parse(int c, char **argv, int invert, unsigned int *flags,
+		 const void *entry, struct xt_entry_target **target)
+{
+	struct xt_set_info_target *myinfo =
+		(struct xt_set_info_target *) (*target)->data;
+
+	switch (c) {
+	case '1':		/* --add-set <set> <flags> */
+		parse_target(argv, invert, flags,
+			     &myinfo->add_set, "add-set");
+		break;
+	case '2':		/* --del-set <set>[:<flags>] <flags> */
+		parse_target(argv, invert, flags,
+			     &myinfo->del_set, "del-set");
+		break;
+
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+static void
+print_target(const char *prefix, const struct xt_set_info *info)
+{
+	int i;
+	char setname[IPSET_MAXNAMELEN];
+
+	if (info->index == IPSET_INVALID_ID)
+		return;
+	get_set_byid(setname, info->index);
+	printf("%s %s", prefix, setname);
+	for (i = 1; i <= IPSET_DIM_MAX; i++) {
+		printf("%s%s",
+		       i == 1 ? " " : ",",
+		       info->flags & (1 << i) ? "src" : "dst");
+	}
+	printf(" ");
+}
+
+static void
+set_target_print(const void *ip, const struct xt_entry_target *target,
+                 int numeric)
+{
+	const struct xt_set_info_target *info = (const void *)target->data;
+
+	print_target("add-set", &info->add_set);
+	print_target("del-set", &info->del_set);
+}
+
+static void
+set_target_save(const void *ip, const struct xt_entry_target *target)
+{
+	const struct xt_set_info_target *info = (const void *)target->data;
+
+	print_target("--add-set", &info->add_set);
+	print_target("--del-set", &info->del_set);
+}
+
+static struct xtables_target set_tg_reg[] = {
+	{
+		.name		= "SET",
+		.revision	= 0,
+		.version	= XTABLES_VERSION,
+		.family		= NFPROTO_IPV4,
+		.size		= XT_ALIGN(sizeof(struct xt_set_info_target_v0)),
+		.userspacesize	= XT_ALIGN(sizeof(struct xt_set_info_target_v0)),
+		.help		= set_target_help,
+		.init		= set_target_init_v0,
+		.parse		= set_target_parse_v0,
+		.final_check	= set_target_check,
+		.print		= set_target_print_v0,
+		.save		= set_target_save_v0,
+		.extra_opts	= set_target_opts,
+	},
+	{
+		.name		= "SET",
+		.revision	= 1,
+		.version	= XTABLES_VERSION,
+		.family		= NFPROTO_UNSPEC,
+		.size		= XT_ALIGN(sizeof(struct xt_set_info_target)),
+		.userspacesize	= XT_ALIGN(sizeof(struct xt_set_info_target)),
+		.help		= set_target_help,
+		.init		= set_target_init,
+		.parse		= set_target_parse,
+		.final_check	= set_target_check,
+		.print		= set_target_print,
+		.save		= set_target_save,
+		.extra_opts	= set_target_opts,
+	},
+};
+
+void _init(void)
+{
+	xtables_register_targets(set_tg_reg, ARRAY_SIZE(set_tg_reg));
+}
diff --git a/extensions/libxt_SET.man b/extensions/libxt_SET.man
new file mode 100644
index 0000000..ea80c2a
--- /dev/null
+++ b/extensions/libxt_SET.man
@@ -0,0 +1,18 @@
+This modules adds and/or deletes entries from IP sets which can be defined 
+by ipset(8).
+.TP
+\fB\-\-add\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP...]
+add the address(es)/port(s) of the packet to the sets
+.TP
+\fB\-\-del\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP...]
+delete the address(es)/port(s) of the packet from the sets
+.IP
+where flags are
+.BR "src"
+and/or
+.BR "dst"
+specifications and there can be no more than six of them.
+.PP
+Use of -j SET requires that ipset kernel support is provided. As standard
+kernels do not ship this currently, the ipset or Xtables-addons package needs
+to be installed.
diff --git a/extensions/libxt_set.c b/extensions/libxt_set.c
new file mode 100644
index 0000000..75fa3c2
--- /dev/null
+++ b/extensions/libxt_set.c
@@ -0,0 +1,250 @@
+/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
+ *                         Patrick Schaaf <bof@bof.de>
+ *                         Martin Josefsson <gandalf@wlug.westbo.se>
+ * Copyright (C) 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.  
+ */
+
+/* Shared library add-on to iptables to add IP set matching. */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <xtables.h>
+#include <linux/netfilter/xt_set.h>
+#include "libxt_set.h"
+
+static void
+set_help(void)
+{
+	printf("set match options:\n"
+	       " [!] --match-set name flags\n"
+	       "		 'name' is the set name from to match,\n" 
+	       "		 'flags' are the comma separated list of\n"
+	       "		 'src' and 'dst' specifications.\n");
+}
+
+static const struct option set_opts[] = {
+	{ .name = "match-set", .has_arg = true, .val = '1'},
+	{ .name = "set",       .has_arg = true, .val = '2'},
+	{ .name = NULL }
+};
+
+static void
+set_check(unsigned int flags)
+{
+	if (!flags)
+		xtables_error(PARAMETER_PROBLEM,
+			"You must specify `--match-set' with proper arguments");
+}
+
+static int
+set_parse_v0(int c, char **argv, int invert, unsigned int *flags,
+	     const void *entry, struct xt_entry_match **match)
+{
+	struct xt_set_info_match_v0 *myinfo = 
+		(struct xt_set_info_match_v0 *) (*match)->data;
+	struct xt_set_info_v0 *info = &myinfo->match_set;
+
+	switch (c) {
+	case '2':
+		fprintf(stderr,
+			"--set option deprecated, please use --match-set\n");
+	case '1':		/* --match-set <set> <flag>[,<flag> */
+		if (info->u.flags[0])
+			xtables_error(PARAMETER_PROBLEM,
+				      "--match-set can be specified only once");
+
+		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
+		if (invert)
+			info->u.flags[0] |= IPSET_MATCH_INV;
+
+		if (!argv[optind]
+		    || argv[optind][0] == '-'
+		    || argv[optind][0] == '!')
+			xtables_error(PARAMETER_PROBLEM,
+				      "--match-set requires two args.");
+
+		if (strlen(optarg) > IPSET_MAXNAMELEN - 1)
+			xtables_error(PARAMETER_PROBLEM,
+				      "setname `%s' too long, max %d characters.",
+				      optarg, IPSET_MAXNAMELEN - 1);
+
+		get_set_byname(optarg, (struct xt_set_info *)info);
+		parse_dirs_v0(argv[optind], info);
+		DEBUGP("parse: set index %u\n", info->index);
+		optind++;
+		
+		*flags = 1;
+		break;
+
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+static void
+print_match_v0(const char *prefix, const struct xt_set_info_v0 *info)
+{
+	int i;
+	char setname[IPSET_MAXNAMELEN];
+
+	get_set_byid(setname, info->index);
+	printf("%s%s %s", 
+	       (info->u.flags[0] & IPSET_MATCH_INV) ? "! " : "",
+	       prefix,
+	       setname); 
+	for (i = 0; i < IPSET_DIM_MAX; i++) {
+		if (!info->u.flags[i])
+			break;		
+		printf("%s%s",
+		       i == 0 ? " " : ",",
+		       info->u.flags[i] & IPSET_SRC ? "src" : "dst");
+	}
+	printf(" ");
+}
+
+/* Prints out the matchinfo. */
+static void
+set_print_v0(const void *ip, const struct xt_entry_match *match, int numeric)
+{
+	const struct xt_set_info_match_v0 *info = (const void *)match->data;
+
+	print_match_v0("match-set", &info->match_set);
+}
+
+static void
+set_save_v0(const void *ip, const struct xt_entry_match *match)
+{
+	const struct xt_set_info_match_v0 *info = (const void *)match->data;
+
+	print_match_v0("--match-set", &info->match_set);
+}
+
+static int
+set_parse(int c, char **argv, int invert, unsigned int *flags,
+	  const void *entry, struct xt_entry_match **match)
+{
+	struct xt_set_info_match *myinfo = 
+		(struct xt_set_info_match *) (*match)->data;
+	struct xt_set_info *info = &myinfo->match_set;
+
+	switch (c) {
+	case '2':
+		fprintf(stderr,
+			"--set option deprecated, please use --match-set\n");
+	case '1':		/* --match-set <set> <flag>[,<flag> */
+		if (info->dim)
+			xtables_error(PARAMETER_PROBLEM,
+				      "--match-set can be specified only once");
+
+		xtables_check_inverse(optarg, &invert, &optind, 0, argv);
+		if (invert)
+			info->flags |= IPSET_INV_MATCH;
+
+		if (!argv[optind]
+		    || argv[optind][0] == '-'
+		    || argv[optind][0] == '!')
+			xtables_error(PARAMETER_PROBLEM,
+				      "--match-set requires two args.");
+
+		if (strlen(optarg) > IPSET_MAXNAMELEN - 1)
+			xtables_error(PARAMETER_PROBLEM,
+				      "setname `%s' too long, max %d characters.",
+				      optarg, IPSET_MAXNAMELEN - 1);
+
+		get_set_byname(optarg, info);
+		parse_dirs(argv[optind], info);
+		DEBUGP("parse: set index %u\n", info->index);
+		optind++;
+		
+		*flags = 1;
+		break;
+
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+static void
+print_match(const char *prefix, const struct xt_set_info *info)
+{
+	int i;
+	char setname[IPSET_MAXNAMELEN];
+
+	get_set_byid(setname, info->index);
+	printf("%s%s %s", 
+	       (info->flags & IPSET_INV_MATCH) ? "! " : "",
+	       prefix,
+	       setname); 
+	for (i = 1; i <= info->dim; i++) {		
+		printf("%s%s",
+		       i == 1 ? " " : ",",
+		       info->flags & (1 << i) ? "src" : "dst");
+	}
+	printf(" ");
+}
+
+/* Prints out the matchinfo. */
+static void
+set_print(const void *ip, const struct xt_entry_match *match, int numeric)
+{
+	const struct xt_set_info_match *info = (const void *)match->data;
+
+	print_match("match-set", &info->match_set);
+}
+
+static void
+set_save(const void *ip, const struct xt_entry_match *match)
+{
+	const struct xt_set_info_match *info = (const void *)match->data;
+
+	print_match("--match-set", &info->match_set);
+}
+
+static struct xtables_match set_mt_reg[] = {
+	{
+		.name		= "set",
+		.revision	= 0,
+		.version	= XTABLES_VERSION,
+		.family		= NFPROTO_IPV4,
+		.size		= XT_ALIGN(sizeof(struct xt_set_info_match_v0)),
+		.userspacesize	= XT_ALIGN(sizeof(struct xt_set_info_match_v0)),
+		.help		= set_help,
+		.parse		= set_parse_v0,
+		.final_check	= set_check,
+		.print		= set_print_v0,
+		.save		= set_save_v0,
+		.extra_opts	= set_opts,
+	},
+	{
+		.name		= "set",
+		.revision	= 1,
+		.version	= XTABLES_VERSION,
+		.family		= NFPROTO_UNSPEC,
+		.size		= XT_ALIGN(sizeof(struct xt_set_info_match)),
+		.userspacesize	= XT_ALIGN(sizeof(struct xt_set_info_match)),
+		.help		= set_help,
+		.parse		= set_parse,
+		.final_check	= set_check,
+		.print		= set_print,
+		.save		= set_save,
+		.extra_opts	= set_opts,
+	},
+};
+
+void _init(void)
+{
+	xtables_register_matches(set_mt_reg, ARRAY_SIZE(set_mt_reg));
+}
diff --git a/extensions/libxt_set.h b/extensions/libxt_set.h
new file mode 100644
index 0000000..6b93691
--- /dev/null
+++ b/extensions/libxt_set.h
@@ -0,0 +1,147 @@
+#ifndef _LIBXT_SET_H
+#define _LIBXT_SET_H
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+#ifdef DEBUG
+#define DEBUGP(x, args...) fprintf(stderr, x , ## args)
+#else
+#define DEBUGP(x, args...) 
+#endif
+
+static int
+get_version(unsigned *version)
+{
+	int res, sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+	struct ip_set_req_version req_version;
+	socklen_t size = sizeof(req_version);
+	
+	if (sockfd < 0)
+		xtables_error(OTHER_PROBLEM,
+			      "Can't open socket to ipset.\n");
+
+	req_version.op = IP_SET_OP_VERSION;
+	res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size);
+	if (res != 0)
+		xtables_error(OTHER_PROBLEM,
+			      "Kernel module xt_set is not loaded in.\n");
+
+	*version = req_version.version;
+	
+	return sockfd;
+}
+
+static void
+get_set_byid(char *setname, ip_set_id_t idx)
+{
+	struct ip_set_req_get_set req;
+	socklen_t size = sizeof(struct ip_set_req_get_set);
+	int res, sockfd;
+
+	sockfd = get_version(&req.version);
+	req.op = IP_SET_OP_GET_BYINDEX;
+	req.set.index = idx;
+	res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size);
+	close(sockfd);
+
+	if (res != 0)
+		xtables_error(OTHER_PROBLEM,
+			"Problem when communicating with ipset, errno=%d.\n",
+			errno);
+	if (size != sizeof(struct ip_set_req_get_set))
+		xtables_error(OTHER_PROBLEM,
+			"Incorrect return size from kernel during ipset lookup, "
+			"(want %zu, got %zu)\n",
+			sizeof(struct ip_set_req_get_set), (size_t)size);
+	if (req.set.name[0] == '\0')
+		xtables_error(PARAMETER_PROBLEM,
+			"Set with index %i in kernel doesn't exist.\n", idx);
+
+	strncpy(setname, req.set.name, IPSET_MAXNAMELEN);
+}
+
+static void
+get_set_byname(const char *setname, struct xt_set_info *info)
+{
+	struct ip_set_req_get_set req;
+	socklen_t size = sizeof(struct ip_set_req_get_set);
+	int res, sockfd;
+
+	sockfd = get_version(&req.version);
+	req.op = IP_SET_OP_GET_BYNAME;
+	strncpy(req.set.name, setname, IPSET_MAXNAMELEN);
+	req.set.name[IPSET_MAXNAMELEN - 1] = '\0';
+	res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size);
+	close(sockfd);
+
+	if (res != 0)
+		xtables_error(OTHER_PROBLEM,
+			"Problem when communicating with ipset, errno=%d.\n",
+			errno);
+	if (size != sizeof(struct ip_set_req_get_set))
+		xtables_error(OTHER_PROBLEM,
+			"Incorrect return size from kernel during ipset lookup, "
+			"(want %zu, got %zu)\n",
+			sizeof(struct ip_set_req_get_set), (size_t)size);
+	if (req.set.index == IPSET_INVALID_ID)
+		xtables_error(PARAMETER_PROBLEM,
+			      "Set %s doesn't exist.\n", setname);
+
+	info->index = req.set.index;
+}
+
+static void
+parse_dirs_v0(const char *opt_arg, struct xt_set_info_v0 *info)
+{
+	char *saved = strdup(opt_arg);
+	char *ptr, *tmp = saved;
+	int i = 0;
+	
+	while (i < (IPSET_DIM_MAX - 1) && tmp != NULL) {
+		ptr = strsep(&tmp, ",");
+		if (strncmp(ptr, "src", 3) == 0)
+			info->u.flags[i++] |= IPSET_SRC;
+		else if (strncmp(ptr, "dst", 3) == 0)
+			info->u.flags[i++] |= IPSET_DST;
+		else
+			xtables_error(PARAMETER_PROBLEM,
+				"You must spefify (the comma separated list of) 'src' or 'dst'.");
+	}
+
+	if (tmp)
+		xtables_error(PARAMETER_PROBLEM,
+			      "Can't be more src/dst options than %i.", 
+			      IPSET_DIM_MAX - 1);
+
+	free(saved);
+}
+
+static void
+parse_dirs(const char *opt_arg, struct xt_set_info *info)
+{
+	char *saved = strdup(opt_arg);
+	char *ptr, *tmp = saved;
+	int i = 0;
+	
+	while (i < (IPSET_DIM_MAX - 1) && tmp != NULL) {
+		info->dim++;
+		ptr = strsep(&tmp, ",");
+		if (strncmp(ptr, "src", 3) == 0)
+			info->flags |= (1 << info->dim);
+		else if (strncmp(ptr, "dst", 3) != 0)
+			xtables_error(PARAMETER_PROBLEM,
+				"You must spefify (the comma separated list of) 'src' or 'dst'.");
+	}
+
+	if (tmp)
+		xtables_error(PARAMETER_PROBLEM,
+			      "Can't be more src/dst options than %i.", 
+			      IPSET_DIM_MAX - 1);
+
+	free(saved);
+}
+
+#endif /*_LIBXT_SET_H*/
diff --git a/extensions/libxt_set.man b/extensions/libxt_set.man
new file mode 100644
index 0000000..aca1bfc
--- /dev/null
+++ b/extensions/libxt_set.man
@@ -0,0 +1,23 @@
+This module matches IP sets which can be defined by ipset(8).
+.TP
+[\fB!\fP] \fB\-\-match\-set\fP \fIsetname\fP \fIflag\fP[\fB,\fP\fIflag\fP]...
+where flags are the comma separated list of
+.BR "src"
+and/or
+.BR "dst" 
+specifications and there can be no more than six of them. Hence the command
+.IP
+ iptables \-A FORWARD \-m set \-\-match\-set test src,dst
+.IP
+will match packets, for which (if the set type is ipportmap) the source
+address and destination port pair can be found in the specified set. If
+the set type of the specified set is single dimension (for example ipmap),
+then the command will match packets for which the source address can be
+found in the specified set. 
+.PP
+The option \fB\-\-match\-set\fR can be replaced by \fB\-\-set\fR if that does 
+not clash with an option of other extensions.
+.PP
+Use of -m set requires that ipset kernel support is provided. As standard
+kernels do not ship this currently, the ipset or Xtables-addons package needs
+to be installed.
diff --git a/include/linux/netfilter/xt_set.h b/include/linux/netfilter/xt_set.h
new file mode 100644
index 0000000..3ad3137
--- /dev/null
+++ b/include/linux/netfilter/xt_set.h
@@ -0,0 +1,110 @@
+#ifndef _XT_SET_H
+#define _XT_SET_H
+
+/* The protocol version */
+#define IPSET_PROTOCOL		5
+
+/* The max length of strings including NUL: set and type identifiers */
+#define IPSET_MAXNAMELEN	32
+
+/* 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 uint16_t 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),
+};
+
+/* 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;
+};
+
+/* 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 {
+		u_int32_t flags[IPSET_DIM_MAX + 1];
+		struct {
+			u_int32_t __flags[IPSET_DIM_MAX];
+			u_int8_t dim;
+			u_int8_t 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: current interface to netfilter/iptables */
+
+struct xt_set_info {
+	ip_set_id_t index;
+	u_int8_t dim;
+	u_int8_t flags;
+};
+
+/* match and target infos */
+struct xt_set_info_match {
+	struct xt_set_info match_set;
+};
+
+struct xt_set_info_target {
+	struct xt_set_info add_set;
+	struct xt_set_info del_set;
+};
+
+#endif /*_XT_SET_H*/
diff --git a/include/linux/netfilter_ipv4/ip_set.h b/include/linux/netfilter_ipv4/ip_set.h
deleted file mode 100644
index 92a746e..0000000
--- a/include/linux/netfilter_ipv4/ip_set.h
+++ /dev/null
@@ -1,498 +0,0 @@
-#ifndef _IP_SET_H
-#define _IP_SET_H
-
-/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
- *                         Patrick Schaaf <bof@bof.de>
- *                         Martin Josefsson <gandalf@wlug.westbo.se>
- * Copyright (C) 2003-2004 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.  
- */
-
-#if 0
-#define IP_SET_DEBUG
-#endif
-
-/*
- * A sockopt of such quality has hardly ever been seen before on the open
- * market!  This little beauty, hardly ever used: above 64, so it's
- * traditionally used for firewalling, not touched (even once!) by the
- * 2.0, 2.2 and 2.4 kernels!
- *
- * Comes with its own certificate of authenticity, valid anywhere in the
- * Free world!
- *
- * Rusty, 19.4.2000
- */
-#define SO_IP_SET 		83
-
-/*
- * Heavily modify by Joakim Axelsson 08.03.2002
- * - Made it more modulebased
- *
- * Additional heavy modifications by Jozsef Kadlecsik 22.02.2004
- * - bindings added
- * - in order to "deal with" backward compatibility, renamed to ipset
- */
-
-/* 
- * Used so that the kernel module and ipset-binary can match their versions 
- */
-#define IP_SET_PROTOCOL_VERSION 2
-
-#define IP_SET_MAXNAMELEN 32	/* set names and set typenames */
-
-/* Lets work with our own typedef for representing an IP address.
- * We hope to make the code more portable, possibly to IPv6...
- *
- * The representation works in HOST byte order, because most set types
- * will perform arithmetic operations and compare operations.
- * 
- * For now the type is an uint32_t.
- *
- * Make sure to ONLY use the functions when translating and parsing
- * in order to keep the host byte order and make it more portable:
- *  parse_ip()
- *  parse_mask()
- *  parse_ipandmask()
- *  ip_tostring()
- * (Joakim: where are they???)
- */
-
-typedef uint32_t ip_set_ip_t;
-
-/* Sets are identified by an id in kernel space. Tweak with ip_set_id_t
- * and IP_SET_INVALID_ID if you want to increase the max number of sets.
- */
-typedef uint16_t ip_set_id_t;
-
-#define IP_SET_INVALID_ID	65535
-
-/* How deep we follow bindings */
-#define IP_SET_MAX_BINDINGS	6
-
-/*
- * Option flags for kernel operations (ipt_set_info)
- */
-#define IPSET_SRC 		0x01	/* Source match/add */
-#define IPSET_DST		0x02	/* Destination match/add */
-#define IPSET_MATCH_INV		0x04	/* Inverse matching */
-
-/*
- * Set features
- */
-#define IPSET_TYPE_IP		0x01	/* IP address type of set */
-#define IPSET_TYPE_PORT		0x02	/* Port type of set */
-#define IPSET_DATA_SINGLE	0x04	/* Single data storage */
-#define IPSET_DATA_DOUBLE	0x08	/* Double data storage */
-
-/* Reserved keywords */
-#define IPSET_TOKEN_DEFAULT	":default:"
-#define IPSET_TOKEN_ALL		":all:"
-
-/* SO_IP_SET operation constants, and their request struct types.
- *
- * Operation ids:
- *	  0-99:	 commands with version checking
- *	100-199: add/del/test/bind/unbind
- *	200-299: list, save, restore
- */
-
-/* Single shot operations: 
- * version, create, destroy, flush, rename and swap 
- *
- * Sets are identified by name.
- */
-
-#define IP_SET_REQ_STD		\
-	unsigned op;		\
-	unsigned version;	\
-	char name[IP_SET_MAXNAMELEN]
-
-#define IP_SET_OP_CREATE	0x00000001	/* Create a new (empty) set */
-struct ip_set_req_create {
-	IP_SET_REQ_STD;
-	char typename[IP_SET_MAXNAMELEN];
-};
-
-#define IP_SET_OP_DESTROY	0x00000002	/* Remove a (empty) set */
-struct ip_set_req_std {
-	IP_SET_REQ_STD;
-};
-
-#define IP_SET_OP_FLUSH		0x00000003	/* Remove all IPs in a set */
-/* Uses ip_set_req_std */
-
-#define IP_SET_OP_RENAME	0x00000004	/* Rename a set */
-/* Uses ip_set_req_create */
-
-#define IP_SET_OP_SWAP		0x00000005	/* Swap two sets */
-/* Uses ip_set_req_create */
-
-union ip_set_name_index {
-	char name[IP_SET_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;
-};
-
-/* Double shots operations: 
- * add, del, test, bind and unbind.
- *
- * First we query the kernel to get the index and type of the target set,
- * then issue the command. Validity of IP is checked in kernel in order
- * to minimalize sockopt operations.
- */
-
-/* Get minimal set data for add/del/test/bind/unbind IP */
-#define IP_SET_OP_ADT_GET	0x00000010	/* Get set and type */
-struct ip_set_req_adt_get {
-	unsigned op;
-	unsigned version;
-	union ip_set_name_index set;
-	char typename[IP_SET_MAXNAMELEN];
-};
-
-#define IP_SET_REQ_BYINDEX	\
-	unsigned op;		\
-	ip_set_id_t index;
-
-struct ip_set_req_adt {
-	IP_SET_REQ_BYINDEX;
-};
-
-#define IP_SET_OP_ADD_IP	0x00000101	/* Add an IP to a set */
-/* Uses ip_set_req_adt, with type specific addage */
-
-#define IP_SET_OP_DEL_IP	0x00000102	/* Remove an IP from a set */
-/* Uses ip_set_req_adt, with type specific addage */
-
-#define IP_SET_OP_TEST_IP	0x00000103	/* Test an IP in a set */
-/* Uses ip_set_req_adt, with type specific addage */
-
-#define IP_SET_OP_BIND_SET	0x00000104	/* Bind an IP to a set */
-/* Uses ip_set_req_bind, with type specific addage */
-struct ip_set_req_bind {
-	IP_SET_REQ_BYINDEX;
-	char binding[IP_SET_MAXNAMELEN];
-};
-
-#define IP_SET_OP_UNBIND_SET	0x00000105	/* Unbind an IP from a set */
-/* Uses ip_set_req_bind, with type speficic addage 
- * index = 0 means unbinding for all sets */
-
-#define IP_SET_OP_TEST_BIND_SET	0x00000106	/* Test binding an IP to a set */
-/* Uses ip_set_req_bind, with type specific addage */
-
-/* Multiple shots operations: list, save, restore.
- *
- * - check kernel version and query the max number of sets
- * - get the basic information on all sets
- *   and size required for the next step
- * - get actual set data: header, data, bindings
- */
-
-/* Get max_sets and the index of a queried set
- */
-#define IP_SET_OP_MAX_SETS	0x00000020
-struct ip_set_req_max_sets {
-	unsigned op;
-	unsigned version;
-	ip_set_id_t max_sets;		/* max_sets */
-	ip_set_id_t sets;		/* real number of sets */
-	union ip_set_name_index set;	/* index of set if name used */
-};
-
-/* Get the id and name of the sets plus size for next step */
-#define IP_SET_OP_LIST_SIZE	0x00000201
-#define IP_SET_OP_SAVE_SIZE	0x00000202
-struct ip_set_req_setnames {
-	unsigned op;
-	ip_set_id_t index;		/* set to list/save */
-	size_t size;			/* size to get setdata/bindings */
-	/* followed by sets number of struct ip_set_name_list */
-};
-
-struct ip_set_name_list {
-	char name[IP_SET_MAXNAMELEN];
-	char typename[IP_SET_MAXNAMELEN];
-	ip_set_id_t index;
-	ip_set_id_t id;
-};
-
-/* The actual list operation */
-#define IP_SET_OP_LIST		0x00000203
-struct ip_set_req_list {
-	IP_SET_REQ_BYINDEX;
-	/* sets number of struct ip_set_list in reply */ 
-};
-
-struct ip_set_list {
-	ip_set_id_t index;
-	ip_set_id_t binding;
-	u_int32_t ref;
-	size_t header_size;	/* Set header data of header_size */
-	size_t members_size;	/* Set members data of members_size */
-	size_t bindings_size;	/* Set bindings data of bindings_size */
-};
-
-struct ip_set_hash_list {
-	ip_set_ip_t ip;
-	ip_set_id_t binding;
-};
-
-/* The save operation */
-#define IP_SET_OP_SAVE		0x00000204
-/* Uses ip_set_req_list, in the reply replaced by
- * sets number of struct ip_set_save plus a marker
- * ip_set_save followed by ip_set_hash_save structures.
- */
-struct ip_set_save {
-	ip_set_id_t index;
-	ip_set_id_t binding;
-	size_t header_size;	/* Set header data of header_size */
-	size_t members_size;	/* Set members data of members_size */
-};
-
-/* At restoring, ip == 0 means default binding for the given set: */
-struct ip_set_hash_save {
-	ip_set_ip_t ip;
-	ip_set_id_t id;
-	ip_set_id_t binding;
-};
-
-/* The restore operation */
-#define IP_SET_OP_RESTORE	0x00000205
-/* Uses ip_set_req_setnames followed by ip_set_restore structures
- * plus a marker ip_set_restore, followed by ip_set_hash_save 
- * structures.
- */
-struct ip_set_restore {
-	char name[IP_SET_MAXNAMELEN];
-	char typename[IP_SET_MAXNAMELEN];
-	ip_set_id_t index;
-	size_t header_size;	/* Create data of header_size */
-	size_t members_size;	/* Set members data of members_size */
-};
-
-static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b)
-{
-	return 4 * ((((b - a + 8) / 8) + 3) / 4);
-}
-
-#ifdef __KERNEL__
-
-#define ip_set_printk(format, args...) 			\
-	do {							\
-		printk("%s: %s: ", __FILE__, __FUNCTION__);	\
-		printk(format "\n" , ## args);			\
-	} while (0)
-
-#if defined(IP_SET_DEBUG)
-#define DP(format, args...) 					\
-	do {							\
-		printk("%s: %s (DBG): ", __FILE__, __FUNCTION__);\
-		printk(format "\n" , ## args);			\
-	} while (0)
-#define IP_SET_ASSERT(x)					\
-	do {							\
-		if (!(x))					\
-			printk("IP_SET_ASSERT: %s:%i(%s)\n",	\
-				__FILE__, __LINE__, __FUNCTION__); \
-	} while (0)
-#else
-#define DP(format, args...)
-#define IP_SET_ASSERT(x)
-#endif
-
-struct ip_set;
-
-/*
- * The ip_set_type definition - one per set type, e.g. "ipmap".
- *
- * Each individual set has a pointer, set->type, going to one
- * of these structures. Function pointers inside the structure implement
- * the real behaviour of the sets.
- *
- * If not mentioned differently, the implementation behind the function
- * pointers of a set_type, is expected to return 0 if ok, and a negative
- * errno (e.g. -EINVAL) on error.
- */
-struct ip_set_type {
-	struct list_head list;	/* next in list of set types */
-
-	/* test for IP in set (kernel: iptables -m set src|dst)
-	 * return 0 if not in set, 1 if in set.
-	 */
-	int (*testip_kernel) (struct ip_set *set,
-			      const struct sk_buff * skb, 
-			      ip_set_ip_t *ip,
-			      const u_int32_t *flags,
-			      unsigned char index);
-
-	/* test for IP in set (userspace: ipset -T set IP)
-	 * return 0 if not in set, 1 if in set.
-	 */
-	int (*testip) (struct ip_set *set,
-		       const void *data, size_t size,
-		       ip_set_ip_t *ip);
-
-	/*
-	 * Size of the data structure passed by when
-	 * adding/deletin/testing an entry.
-	 */
-	size_t reqsize;
-
-	/* Add IP into set (userspace: ipset -A set IP)
-	 * Return -EEXIST if the address is already in the set,
-	 * and -ERANGE if the address lies outside the set bounds.
-	 * If the address was not already in the set, 0 is returned.
-	 */
-	int (*addip) (struct ip_set *set, 
-		      const void *data, size_t size,
-		      ip_set_ip_t *ip);
-
-	/* Add IP into set (kernel: iptables ... -j SET set src|dst)
-	 * Return -EEXIST if the address is already in the set,
-	 * and -ERANGE if the address lies outside the set bounds.
-	 * If the address was not already in the set, 0 is returned.
-	 */
-	int (*addip_kernel) (struct ip_set *set,
-			     const struct sk_buff * skb, 
-			     ip_set_ip_t *ip,
-			     const u_int32_t *flags,
-			     unsigned char index);
-
-	/* remove IP from set (userspace: ipset -D set --entry x)
-	 * Return -EEXIST if the address is NOT in the set,
-	 * and -ERANGE if the address lies outside the set bounds.
-	 * If the address really was in the set, 0 is returned.
-	 */
-	int (*delip) (struct ip_set *set, 
-		      const void *data, size_t size,
-		      ip_set_ip_t *ip);
-
-	/* remove IP from set (kernel: iptables ... -j SET --entry x)
-	 * Return -EEXIST if the address is NOT in the set,
-	 * and -ERANGE if the address lies outside the set bounds.
-	 * If the address really was in the set, 0 is returned.
-	 */
-	int (*delip_kernel) (struct ip_set *set,
-			     const struct sk_buff * skb, 
-			     ip_set_ip_t *ip,
-			     const u_int32_t *flags,
-			     unsigned char index);
-
-	/* new set creation - allocated type specific items
-	 */
-	int (*create) (struct ip_set *set,
-		       const void *data, size_t size);
-
-	/* retry the operation after successfully tweaking the set
-	 */
-	int (*retry) (struct ip_set *set);
-
-	/* set destruction - free type specific items
-	 * There is no return value.
-	 * Can be called only when child sets are destroyed.
-	 */
-	void (*destroy) (struct ip_set *set);
-
-	/* set flushing - reset all bits in the set, or something similar.
-	 * There is no return value.
-	 */
-	void (*flush) (struct ip_set *set);
-
-	/* Listing: size needed for header
-	 */
-	size_t header_size;
-
-	/* Listing: Get the header
-	 *
-	 * Fill in the information in "data".
-	 * This function is always run after list_header_size() under a 
-	 * writelock on the set. Therefor is the length of "data" always 
-	 * correct. 
-	 */
-	void (*list_header) (const struct ip_set *set, 
-			     void *data);
-
-	/* Listing: Get the size for the set members
-	 */
-	int (*list_members_size) (const struct ip_set *set);
-
-	/* Listing: Get the set members
-	 *
-	 * Fill in the information in "data".
-	 * This function is always run after list_member_size() under a 
-	 * writelock on the set. Therefor is the length of "data" always 
-	 * correct. 
-	 */
-	void (*list_members) (const struct ip_set *set,
-			      void *data);
-
-	char typename[IP_SET_MAXNAMELEN];
-	unsigned char features;
-	int protocol_version;
-
-	/* Set this to THIS_MODULE if you are a module, otherwise NULL */
-	struct module *me;
-};
-
-extern int ip_set_register_set_type(struct ip_set_type *set_type);
-extern void ip_set_unregister_set_type(struct ip_set_type *set_type);
-
-/* A generic ipset */
-struct ip_set {
-	char name[IP_SET_MAXNAMELEN];	/* the name of the set */
-	rwlock_t lock;			/* lock for concurrency control */
-	ip_set_id_t id;			/* set id for swapping */
-	ip_set_id_t binding;		/* default binding for the set */
-	atomic_t ref;			/* in kernel and in hash references */
-	struct ip_set_type *type; 	/* the set types */
-	void *data;			/* pooltype specific data */
-};
-
-/* Structure to bind set elements to sets */
-struct ip_set_hash {
-	struct list_head list;		/* list of clashing entries in hash */
-	ip_set_ip_t ip;			/* ip from set */
-	ip_set_id_t id;			/* set id */
-	ip_set_id_t binding;		/* set we bind the element to */
-};
-
-/* register and unregister set references */
-extern ip_set_id_t ip_set_get_byname(const char name[IP_SET_MAXNAMELEN]);
-extern ip_set_id_t ip_set_get_byindex(ip_set_id_t id);
-extern void ip_set_put(ip_set_id_t id);
-
-/* API for iptables set match, and SET target */
-extern void ip_set_addip_kernel(ip_set_id_t id,
-				const struct sk_buff *skb,
-				const u_int32_t *flags);
-extern void ip_set_delip_kernel(ip_set_id_t id,
-				const struct sk_buff *skb,
-				const u_int32_t *flags);
-extern int ip_set_testip_kernel(ip_set_id_t id,
-				const struct sk_buff *skb,
-				const u_int32_t *flags);
-
-#endif				/* __KERNEL__ */
-
-#endif /*_IP_SET_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_set.h b/include/linux/netfilter_ipv4/ipt_set.h
deleted file mode 100644
index 2a18b93..0000000
--- a/include/linux/netfilter_ipv4/ipt_set.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _IPT_SET_H
-#define _IPT_SET_H
-
-#include <linux/netfilter_ipv4/ip_set.h>
-
-struct ipt_set_info {
-	ip_set_id_t index;
-	u_int32_t flags[IP_SET_MAX_BINDINGS + 1];
-};
-
-/* match info */
-struct ipt_set_info_match {
-	struct ipt_set_info match_set;
-};
-
-struct ipt_set_info_target {
-	struct ipt_set_info add_set;
-	struct ipt_set_info del_set;
-};
-
-#endif /*_IPT_SET_H*/
-- 
1.8.1.4

