From cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adf Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 4 Sep 2012 05:24:47 +0200 Subject: 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 --- configure.ac | 4 ++-- include/xtables.h | 3 +++ iptables/ip6tables.c | 7 ++++++- iptables/iptables.c | 8 +++++++- libxtables/xtables.c | 32 +++++++++++++++++++++++++------- 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. */ -- cgit v1.2.3