summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@inai.de>2012-09-04 05:24:47 +0200
committerJan Engelhardt <jengelh@inai.de>2012-09-27 23:36:58 +0200
commitcd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adf (patch)
treefb1ab73ce71c44406051d024b2fba40b88dd97b5
parent954b76c317f641b7faf33cc26931d45585cc0dea (diff)
iptables: support for target aliases
This patch allows for target names listed on the command line to be rewritten to new names and revisions. As before, we will pick a revision that is supported by the kernel - now including real_name in the search. This gives us the possibility to test for many action names. Signed-off-by: Jan Engelhardt <jengelh@inai.de>
-rw-r--r--configure.ac4
-rw-r--r--include/xtables.h3
-rw-r--r--iptables/ip6tables.c7
-rw-r--r--iptables/iptables.c8
-rw-r--r--libxtables/xtables.c32
5 files changed, 43 insertions, 11 deletions
diff --git a/configure.ac b/configure.ac
index 4060f901..adda50e4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,8 +2,8 @@
AC_INIT([iptables], [1.4.15])
# See libtool.info "Libtool's versioning system"
-libxtables_vcurrent=8
-libxtables_vage=1
+libxtables_vcurrent=9
+libxtables_vage=0
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
diff --git a/include/xtables.h b/include/xtables.h
index 3b15e67e..7bdc331c 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -282,6 +282,9 @@ struct xtables_target
const char *name;
+ /* Real target behind this, if any. */
+ const char *real_name;
+
/* Revision of target (0 by default). */
u_int8_t revision;
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index b191d5df..752cf033 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -1286,8 +1286,13 @@ static void command_jump(struct iptables_command_state *cs)
cs->target->t = xtables_calloc(1, size);
cs->target->t->u.target_size = size;
- strcpy(cs->target->t->u.user.name, cs->jumpto);
+ strcpy(cs->target->t->u.user.name, cs->target->real_name);
cs->target->t->u.user.revision = cs->target->revision;
+ if (cs->target->real_name != cs->target->name)
+ fprintf(stderr, "WARNING: The %s target is obsolete. "
+ "Use %s instead.\n",
+ cs->jumpto, cs->target->real_name);
+
xs_init_target(cs->target);
if (cs->target->x6_options != NULL)
opts = xtables_options_xfrm(ip6tables_globals.orig_opts, opts,
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 03ac63b8..a237e93c 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -1295,8 +1295,14 @@ static void command_jump(struct iptables_command_state *cs)
cs->target->t = xtables_calloc(1, size);
cs->target->t->u.target_size = size;
- strcpy(cs->target->t->u.user.name, cs->jumpto);
+ strcpy(cs->target->t->u.user.name, cs->target->real_name);
cs->target->t->u.user.revision = cs->target->revision;
+ if (cs->target->real_name != cs->target->name)
+ /* Alias support for userspace side */
+ fprintf(stderr, "WARNING: The %s target is obsolete. "
+ "Use %s instead.\n",
+ cs->jumpto, cs->target->real_name);
+
xs_init_target(cs->target);
if (cs->target->x6_options != NULL)
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index 7f0d3ccb..a2b24c5a 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -872,9 +872,18 @@ void xtables_register_match(struct xtables_match *me)
* preferred.
*/
static int
-xtables_mt_prefer(unsigned int a_rev, unsigned int a_fam,
- unsigned int b_rev, unsigned int b_fam)
+xtables_mt_prefer(bool a_alias, unsigned int a_rev, unsigned int a_fam,
+ bool b_alias, unsigned int b_rev, unsigned int b_fam)
{
+ /*
+ * Alias ranks higher than no alias.
+ * (We want the new action to be used whenever possible.)
+ */
+ if (!a_alias && b_alias)
+ return -1;
+ if (a_alias && !b_alias)
+ return 1;
+
/* Higher revision ranks higher. */
if (a_rev < b_rev)
return -1;
@@ -894,14 +903,21 @@ xtables_mt_prefer(unsigned int a_rev, unsigned int a_fam,
static int xtables_match_prefer(const struct xtables_match *a,
const struct xtables_match *b)
{
- return xtables_mt_prefer(a->revision, a->family,
- b->revision, b->family);
+ return xtables_mt_prefer(false, a->revision, a->family,
+ false, b->revision, b->family);
}
static int xtables_target_prefer(const struct xtables_target *a,
const struct xtables_target *b)
{
- return xtables_mt_prefer(a->revision, a->family,
+ /*
+ * Note that if x->real_name==NULL, it will be set to x->name in
+ * xtables_register_*; the direct pointer comparison here is therefore
+ * legitimate to detect an alias.
+ */
+ return xtables_mt_prefer(a->name != a->real_name,
+ a->revision, a->family,
+ b->name != b->real_name,
b->revision, b->family);
}
@@ -985,6 +1001,8 @@ void xtables_register_target(struct xtables_target *me)
exit(1);
}
+ if (me->real_name == NULL)
+ me->real_name = me->name;
if (me->x6_options != NULL)
xtables_option_metavalidate(me->name, me->x6_options);
if (me->extra_opts != NULL)
@@ -1018,11 +1036,11 @@ static void xtables_fully_register_pending_target(struct xtables_target *me)
/* Now we have two (or more) options, check compatibility. */
if (compare > 0 &&
- compatible_target_revision(old->name, old->revision))
+ compatible_target_revision(old->real_name, old->revision))
return;
/* See if new target can be used. */
- if (!compatible_target_revision(me->name, me->revision))
+ if (!compatible_target_revision(me->real_name, me->revision))
return;
/* Delete old one. */