free(m);
m = nm;
}
+
+ if (cs->target) {
+ free(cs->target->t);
+ cs->target->t = NULL;
+
+ if (cs->target == cs->target->next) {
+ free(cs->target);
+ cs->target = NULL;
+ }
+ }
}
static void ebt_print_mac(const unsigned char *mac)
*/
#define EBT_TABLE_MAXNAMELEN 32
-#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
/* verdicts >0 are "branches" */
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
if (cs->target) {
free(cs->target->t);
cs->target->t = NULL;
+
+ if (cs->target == cs->target->next) {
+ free(cs->target);
+ cs->target = NULL;
+ }
}
}
$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j DROP
$XT_MULTI iptables -D FORWARD -i eth23 -o eth42 -j REJECT
[[ $? -eq 1 ]] || exit 1
+
+# test incorrect deletion of rules with deviating payload
+# in non-standard target
+
+$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j MARK --set-mark 23
+$XT_MULTI iptables -D FORWARD -i eth23 -o eth42 -j MARK --set-mark 42
+[[ $? -eq 1 ]] || exit 1
return rule_nr;
}
-static const char *
-parse_target(const char *targetname)
-{
- const char *ptr;
-
- if (strlen(targetname) < 1)
- xtables_error(PARAMETER_PROBLEM,
- "Invalid target name (too short)");
-
- if (strlen(targetname)+1 > EBT_CHAIN_MAXNAMELEN)
- xtables_error(PARAMETER_PROBLEM,
- "Invalid target '%s' (%d chars max)",
- targetname, EBT_CHAIN_MAXNAMELEN);
-
- for (ptr = targetname; *ptr; ptr++)
- if (isspace(*ptr))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid target name `%s'", targetname);
- return targetname;
-}
-
static int get_current_chain(const char *chain)
{
if (strcmp(chain, "PREROUTING") == 0)
break;
} else if (c == 'j') {
ebt_check_option2(&flags, OPT_JUMP);
- cs.jumpto = parse_target(optarg);
- cs.target = ebt_command_jump(cs.jumpto);
+ command_jump(&cs);
break;
} else if (c == 's') {
ebt_check_option2(&flags, OPT_SOURCE);
return rule_nr;
}
-static const char *
-parse_target(const char *targetname)
-{
- const char *ptr;
-
- if (strlen(targetname) < 1)
- xtables_error(PARAMETER_PROBLEM,
- "Invalid target name (too short)");
-
- if (strlen(targetname)+1 > EBT_CHAIN_MAXNAMELEN)
- xtables_error(PARAMETER_PROBLEM,
- "Invalid target '%s' (%d chars max)",
- targetname, EBT_CHAIN_MAXNAMELEN);
-
- for (ptr = targetname; *ptr; ptr++)
- if (isspace(*ptr))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid target name `%s'", targetname);
- return targetname;
-}
-
static int
append_entry(struct nft_handle *h,
const char *chain,
return merge;
}
-/*
- * More glue code.
- */
-struct xtables_target *ebt_command_jump(const char *jumpto)
-{
- struct xtables_target *target;
- unsigned int verdict;
-
- /* Standard target? */
- if (!ebt_fill_target(jumpto, &verdict))
- jumpto = "standard";
-
- /* For ebtables, all targets are preloaded. Hence it is either in
- * xtables_targets or a custom chain to jump to, in which case
- * returning NULL is fine. */
- for (target = xtables_targets; target; target = target->next) {
- if (!strcmp(target->name, jumpto))
- break;
- }
-
- return target;
-}
-
static void print_help(const struct xtables_target *t,
const struct xtables_rule_match *m, const char *table)
{
} else if (c == 'j') {
ebt_check_option2(&flags, OPT_JUMP);
if (strcmp(optarg, "CONTINUE") != 0) {
- cs.jumpto = parse_target(optarg);
- cs.target = ebt_command_jump(cs.jumpto);
+ command_jump(&cs);
}
break;
} else if (c == 's') {
}
for (ptr = xtables_targets; ptr; ptr = ptr->next) {
- if (extension_cmp(name, ptr->name, ptr->family))
+ if (extension_cmp(name, ptr->name, ptr->family)) {
+ struct xtables_target *clone;
+
+ /* First target of this type: */
+ if (ptr->t == NULL)
+ break;
+
+ /* Second and subsequent clones */
+ clone = xtables_malloc(sizeof(struct xtables_target));
+ memcpy(clone, ptr, sizeof(struct xtables_target));
+ clone->udata = NULL;
+ clone->tflags = 0;
+ /* This is a clone: */
+ clone->next = clone;
+
+ ptr = clone;
break;
+ }
}
#ifndef NO_SHARED_LIBS