summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--iptables/nft-bridge.c36
-rw-r--r--iptables/nft-bridge.h1
-rw-r--r--iptables/xtables-eb-translate.c109
-rw-r--r--iptables/xtables-eb.c77
4 files changed, 58 insertions, 165 deletions
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
index 6854d5b6..7e659bb5 100644
--- a/iptables/nft-bridge.c
+++ b/iptables/nft-bridge.c
@@ -25,45 +25,25 @@
void ebt_cs_clean(struct iptables_command_state *cs)
{
struct ebt_match *m, *nm;
- struct xtables_rule_match *matchp, *tmp;
- for (matchp = cs->matches; matchp;) {
- tmp = matchp->next;
-
- if (matchp->match == matchp->match->next) {
- free(matchp->match);
- matchp->match = NULL;
- }
- free(matchp);
- matchp = tmp;
- }
+ xtables_rule_matches_free(&cs->matches);
for (m = cs->match_list; m;) {
- if (m->ismatch) {
- struct xtables_match *match = m->u.match;
-
- memset(match->m->data, 0,
- match->m->u.match_size - sizeof(*match->m));
- if (match->init)
- match->init(match->m);
- } else {
+ if (!m->ismatch) {
struct xtables_target *target = m->u.watcher;
- memset(target->t->data, 0,
- target->t->u.target_size - sizeof(*target->t));
- if (target->init)
- target->init(target->t);
+ if (target->t) {
+ free(target->t);
+ target->t = NULL;
+ }
+ if (target == target->next)
+ free(target);
}
nm = m->next;
free(m);
m = nm;
}
-
- if (cs->target) {
- if (cs->target->udata_size)
- free(cs->target->udata);
- }
}
/* 0: default, print only 2 digits if necessary
diff --git a/iptables/nft-bridge.h b/iptables/nft-bridge.h
index 601476dd..1fe26bab 100644
--- a/iptables/nft-bridge.h
+++ b/iptables/nft-bridge.h
@@ -121,5 +121,6 @@ void ebt_add_match(struct xtables_match *m,
void ebt_add_watcher(struct xtables_target *watcher,
struct iptables_command_state *cs);
int ebt_command_default(struct iptables_command_state *cs);
+struct xtables_target *ebt_command_jump(const char *jumpto);
#endif
diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c
index 145653d5..fb37b56e 100644
--- a/iptables/xtables-eb-translate.c
+++ b/iptables/xtables-eb-translate.c
@@ -130,72 +130,6 @@ extern struct xtables_globals ebtables_globals;
#define prog_name ebtables_globals.program_name
#define prog_vers ebtables_globals.program_version
-#define OPTION_OFFSET 256
-static struct option *merge_options(struct option *oldopts,
- const struct option *newopts,
- unsigned int *options_offset)
-{
- unsigned int num_old, num_new, i;
- struct option *merge;
-
- if (!newopts || !oldopts || !options_offset)
- return oldopts;
- for (num_old = 0; oldopts[num_old].name; num_old++);
- for (num_new = 0; newopts[num_new].name; num_new++);
-
- ebtables_globals.option_offset += OPTION_OFFSET;
- *options_offset = ebtables_globals.option_offset;
-
- merge = malloc(sizeof(struct option) * (num_new + num_old + 1));
- if (!merge)
- return NULL;
- memcpy(merge, oldopts, num_old * sizeof(struct option));
- for (i = 0; i < num_new; i++) {
- merge[num_old + i] = newopts[i];
- merge[num_old + i].val += *options_offset;
- }
- memset(merge + num_old + num_new, 0, sizeof(struct option));
- /* Only free dynamically allocated stuff */
- if (oldopts != ebt_original_options)
- free(oldopts);
-
- return merge;
-}
-
-/*
- * More glue code.
- */
-static struct xtables_target *command_jump(struct iptables_command_state *cs,
- const char *jumpto)
-{
- struct xtables_target *target;
- size_t size;
-
- /* XTF_TRY_LOAD (may be chain name) */
- target = xtables_find_target(jumpto, XTF_TRY_LOAD);
-
- if (!target)
- return NULL;
-
- size = XT_ALIGN(sizeof(struct xt_entry_target))
- + target->size;
-
- target->t = xtables_calloc(1, size);
- target->t->u.target_size = size;
- snprintf(target->t->u.user.name,
- sizeof(target->t->u.user.name), "%s", jumpto);
- target->t->u.user.name[sizeof(target->t->u.user.name)-1] = '\0';
- target->t->u.user.revision = target->revision;
-
- xs_init_target(target);
-
- opts = merge_options(opts, target->extra_opts, &target->option_offset);
- if (opts == NULL)
- xtables_error(OTHER_PROBLEM, "Can't alloc memory");
-
- return target;
-}
-
static void print_help(void)
{
fprintf(stderr, "%s: Translate ebtables command to nft syntax\n"
@@ -286,8 +220,6 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
int rule_nr_end = 0;
int ret = 0;
unsigned int flags = 0;
- struct xtables_target *t;
- struct xtables_match *m;
struct iptables_command_state cs = {
.argv = argv,
.eb.bitmask = EBT_NOPROTO,
@@ -302,30 +234,6 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
.table = *table,
};
- if (nft_init(h, xtables_bridge) < 0)
- xtables_error(OTHER_PROBLEM,
- "Could not initialize nftables layer.");
-
- h->ops = nft_family_ops_lookup(h->family);
- if (h->ops == NULL)
- xtables_error(PARAMETER_PROBLEM, "Unknown family");
-
- /* manually registering ebt matches, given the original ebtables parser
- * don't use '-m matchname' and the match can't loaded dinamically when
- * the user calls it.
- */
- ebt_load_match_extensions();
-
- /* clear mflags in case do_commandeb gets called a second time
- * (we clear the global list of all matches for security)*/
- for (m = xtables_matches; m; m = m->next)
- m->mflags = 0;
-
- for (t = xtables_targets; t; t = t->next) {
- t->tflags = 0;
- t->used = 0;
- }
-
/* prevent getopt to spoil our error reporting */
opterr = false;
@@ -506,7 +414,7 @@ print_zero:
} else if (c == 'j') {
ebt_check_option2(&flags, OPT_JUMP);
cs.jumpto = parse_target(optarg);
- cs.target = command_jump(&cs, cs.jumpto);
+ cs.target = ebt_command_jump(cs.jumpto);
break;
} else if (c == 's') {
ebt_check_option2(&flags, OPT_SOURCE);
@@ -678,20 +586,11 @@ int xtables_eb_xlate_main(int argc, char *argv[])
{
int ret;
char *table = "filter";
- struct nft_handle h = {
- .family = NFPROTO_BRIDGE,
- };
-
- ebtables_globals.program_name = argv[0];
- ret = xtables_init_all(&ebtables_globals, NFPROTO_BRIDGE);
- if (ret < 0) {
- fprintf(stderr, "%s/%s Failed to initialize xtables\n",
- ebtables_globals.program_name,
- ebtables_globals.program_version);
- exit(EXIT_FAILURE);
- }
+ struct nft_handle h;
+ nft_init_eb(&h, argv[0]);
ebtables_globals.compat_rev = dummy_compat_rev;
+
ret = do_commandeb_xlate(&h, argc, argv, &table);
if (!ret)
fprintf(stderr, "Translation not implemented\n");
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index c4d458d4..6aa1cba3 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -380,7 +380,7 @@ static struct option *merge_options(struct option *oldopts,
/*
* More glue code.
*/
-static struct xtables_target *command_jump(const char *jumpto)
+struct xtables_target *ebt_command_jump(const char *jumpto)
{
struct xtables_target *target;
unsigned int verdict;
@@ -663,24 +663,24 @@ void ebt_load_match_extensions(void)
void ebt_add_match(struct xtables_match *m,
struct iptables_command_state *cs)
{
- struct xtables_rule_match *i, **rule_matches = &cs->matches;
+ struct xtables_rule_match **rule_matches = &cs->matches;
struct xtables_match *newm;
struct ebt_match *newnode, **matchp;
-
- /* match already in rule_matches, skip inclusion */
- for (i = *rule_matches; i; i = i->next) {
- if (strcmp(m->name, i->match->name) == 0) {
- i->match->mflags |= m->mflags;
- return;
- }
- }
+ struct xt_entry_match *m2;
newm = xtables_find_match(m->name, XTF_LOAD_MUST_SUCCEED, rule_matches);
if (newm == NULL)
xtables_error(OTHER_PROBLEM,
"Unable to add match %s", m->name);
+ m2 = xtables_calloc(1, newm->m->u.match_size);
+ memcpy(m2, newm->m, newm->m->u.match_size);
+ memset(newm->m->data, 0, newm->size);
+ xs_init_match(newm);
+ newm->m = m2;
+
newm->mflags = m->mflags;
+ m->mflags = 0;
/* glue code for watchers */
newnode = calloc(1, sizeof(struct ebt_match));
@@ -698,22 +698,28 @@ void ebt_add_match(struct xtables_match *m,
void ebt_add_watcher(struct xtables_target *watcher,
struct iptables_command_state *cs)
{
- struct ebt_match *i, *newnode, **matchp;
+ struct ebt_match *newnode, **matchp;
+ struct xtables_target *clone;
+
+ clone = xtables_malloc(sizeof(struct xtables_target));
+ memcpy(clone, watcher, sizeof(struct xtables_target));
+ clone->udata = NULL;
+ clone->tflags = watcher->tflags;
+ clone->next = clone;
+
+ clone->t = xtables_calloc(1, watcher->t->u.target_size);
+ memcpy(clone->t, watcher->t, watcher->t->u.target_size);
+
+ memset(watcher->t->data, 0, watcher->size);
+ xs_init_target(watcher);
+ watcher->tflags = 0;
- for (i = cs->match_list; i; i = i->next) {
- if (i->ismatch)
- continue;
- if (strcmp(i->u.watcher->name, watcher->name) == 0) {
- i->u.watcher->tflags |= watcher->tflags;
- return;
- }
- }
newnode = calloc(1, sizeof(struct ebt_match));
if (newnode == NULL)
xtables_error(OTHER_PROBLEM, "Unable to alloc memory");
- newnode->u.watcher = watcher;
+ newnode->u.watcher = clone;
for (matchp = &cs->match_list; *matchp; matchp = &(*matchp)->next)
;
@@ -724,6 +730,7 @@ int ebt_command_default(struct iptables_command_state *cs)
{
struct xtables_target *t = cs->target;
struct xtables_match *m;
+ struct ebt_match *matchp;
/* Is it a target option? */
if (t && t->parse) {
@@ -732,6 +739,23 @@ int ebt_command_default(struct iptables_command_state *cs)
return 0;
}
+ /* check previously added matches/watchers to this rule first */
+ for (matchp = cs->match_list; matchp; matchp = matchp->next) {
+ if (matchp->ismatch) {
+ m = matchp->u.match;
+ if (m->parse &&
+ m->parse(cs->c - m->option_offset, cs->argv,
+ ebt_invert, &m->mflags, NULL, &m->m))
+ return 0;
+ } else {
+ t = matchp->u.watcher;
+ if (t->parse &&
+ t->parse(cs->c - t->option_offset, cs->argv,
+ ebt_invert, &t->tflags, NULL, &t->t))
+ return 0;
+ }
+ }
+
/* Is it a match_option? */
for (m = xtables_matches; m; m = m->next) {
if (m->parse &&
@@ -800,7 +824,6 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
int ret = 0;
unsigned int flags = 0;
struct xtables_target *t;
- struct xtables_match *m;
struct iptables_command_state cs = {
.argv = argv,
.eb.bitmask = EBT_NOPROTO,
@@ -812,16 +835,6 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
struct xtables_rule_match *xtrm_i;
struct ebt_match *match;
- /* clear mflags in case do_commandeb gets called a second time
- * (we clear the global list of all matches for security)*/
- for (m = xtables_matches; m; m = m->next)
- m->mflags = 0;
-
- for (t = xtables_targets; t; t = t->next) {
- t->tflags = 0;
- t->used = 0;
- }
-
/* prevent getopt to spoil our error reporting */
optind = 0;
opterr = false;
@@ -1057,7 +1070,7 @@ print_zero:
} else if (c == 'j') {
ebt_check_option2(&flags, OPT_JUMP);
cs.jumpto = parse_target(optarg);
- cs.target = command_jump(cs.jumpto);
+ cs.target = ebt_command_jump(cs.jumpto);
break;
} else if (c == 's') {
ebt_check_option2(&flags, OPT_SOURCE);