From aa37acc1423126f555135935c687eb91995b9440 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 7 Feb 2011 04:00:50 +0100 Subject: libxtables: guided option parser This patchset seeks to drastically reduce the code in the individual extensions by centralizing their argument parsing (breakdown of strings), validation, and in part, assignment. As a secondary goal, this reduces the number of static storage duration variables in flight. Signed-off-by: Jan Engelhardt --- ip6tables.c | 58 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'ip6tables.c') diff --git a/ip6tables.c b/ip6tables.c index 96a0fdcf..83d2fae1 100644 --- a/ip6tables.c +++ b/ip6tables.c @@ -1279,25 +1279,25 @@ static void command_default(struct iptables_command_state *cs) struct xtables_rule_match *matchp; struct xtables_match *m; - if (cs->target != NULL && cs->target->parse != NULL && + if (cs->target != NULL && + (cs->target->parse != NULL || cs->target->x6_parse != NULL) && cs->c >= cs->target->option_offset && cs->c < cs->target->option_offset + XT_OPTION_OFFSET_SCALE) { - cs->target->parse(cs->c - cs->target->option_offset, cs->argv, - cs->invert, &cs->target->tflags, &cs->fw6, - &cs->target->t); + xtables_option_tpcall(cs->c, cs->argv, cs->invert, + cs->target, &cs->fw); return; } for (matchp = cs->matches; matchp; matchp = matchp->next) { m = matchp->match; - if (matchp->completed || m->parse == NULL) + if (matchp->completed || + (m->x6_parse == NULL && m->parse == NULL)) continue; if (cs->c < matchp->match->option_offset || cs->c >= matchp->match->option_offset + XT_OPTION_OFFSET_SCALE) continue; - m->parse(cs->c - m->option_offset, cs->argv, cs->invert, - &m->mflags, &cs->fw6, &m->m); + xtables_option_mpcall(cs->c, cs->argv, cs->invert, m, &cs->fw); return; } @@ -1317,9 +1317,17 @@ static void command_default(struct iptables_command_state *cs) if (m->init != NULL) m->init(m->m); - opts = xtables_merge_options(ip6tables_globals.orig_opts, opts, - m->extra_opts, &m->option_offset); - + if (m->x6_options != NULL) + opts = xtables_options_xfrm(ip6tables_globals.orig_opts, + opts, m->x6_options, + &m->option_offset); + else + opts = xtables_merge_options(ip6tables_globals.orig_opts, + opts, + m->extra_opts, + &m->option_offset); + if (opts == NULL) + xtables_error(OTHER_PROBLEM, "can't alloc memory!"); optind--; return; } @@ -1353,9 +1361,14 @@ static void command_jump(struct iptables_command_state *cs) cs->target->t->u.user.revision = cs->target->revision; if (cs->target->init != NULL) cs->target->init(cs->target->t); - opts = xtables_merge_options(ip6tables_globals.orig_opts, opts, - cs->target->extra_opts, - &cs->target->option_offset); + if (cs->target->x6_options != NULL) + opts = xtables_options_xfrm(ip6tables_globals.orig_opts, opts, + cs->target->x6_options, + &cs->target->option_offset); + else + opts = xtables_merge_options(ip6tables_globals.orig_opts, opts, + cs->target->extra_opts, + &cs->target->option_offset); if (opts == NULL) xtables_error(OTHER_PROBLEM, "can't alloc memory!"); } @@ -1377,8 +1390,13 @@ static void command_match(struct iptables_command_state *cs) m->m->u.user.revision = m->revision; if (m->init != NULL) m->init(m->m); - if (m != m->next) - /* Merge options for non-cloned matches */ + if (m == m->next) + return; + /* Merge options for non-cloned matches */ + if (m->x6_options != NULL) + opts = xtables_options_xfrm(ip6tables_globals.orig_opts, opts, + m->x6_options, &m->option_offset); + else if (m->extra_opts != NULL) opts = xtables_merge_options(ip6tables_globals.orig_opts, opts, m->extra_opts, &m->option_offset); } @@ -1764,10 +1782,18 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand cs.invert = FALSE; } - for (matchp = cs.matches; matchp; matchp = matchp->next) + for (matchp = cs.matches; matchp; matchp = matchp->next) { + if (matchp->match->x6_options != NULL) + xtables_options_fcheck(matchp->match->name, + matchp->match->mflags, + matchp->match->x6_options); if (matchp->match->final_check != NULL) matchp->match->final_check(matchp->match->mflags); + } + if (cs.target != NULL && cs.target->x6_options != NULL) + xtables_options_fcheck(cs.target->name, cs.target->tflags, + cs.target->x6_options); if (cs.target != NULL && cs.target->final_check != NULL) cs.target->final_check(cs.target->tflags); -- cgit v1.2.3 From 3af739b0e7c3b6dcc986645c57c982d0add5006b Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Thu, 10 Feb 2011 16:57:37 +0100 Subject: libxtables: provide better final_check This passes the per-extension data block to the new x6_fcheck function pointer, which can then do last alterations without using hacks like global variables (think libxt_statistic). Signed-off-by: Jan Engelhardt --- ip6tables.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'ip6tables.c') diff --git a/ip6tables.c b/ip6tables.c index 83d2fae1..3beeddf6 100644 --- a/ip6tables.c +++ b/ip6tables.c @@ -1782,20 +1782,10 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand cs.invert = FALSE; } - for (matchp = cs.matches; matchp; matchp = matchp->next) { - if (matchp->match->x6_options != NULL) - xtables_options_fcheck(matchp->match->name, - matchp->match->mflags, - matchp->match->x6_options); - if (matchp->match->final_check != NULL) - matchp->match->final_check(matchp->match->mflags); - } - - if (cs.target != NULL && cs.target->x6_options != NULL) - xtables_options_fcheck(cs.target->name, cs.target->tflags, - cs.target->x6_options); - if (cs.target != NULL && cs.target->final_check != NULL) - cs.target->final_check(cs.target->tflags); + for (matchp = cs.matches; matchp; matchp = matchp->next) + xtables_option_mfcall(matchp->match); + if (cs.target != NULL) + xtables_option_tfcall(cs.target); /* Fix me: must put inverse options checking here --MN */ -- cgit v1.2.3