* @arg: input from command line
* @ext_name: name of extension currently being processed
* @entry: current option being processed
- * @data: per-extension data block
+ * @data: per-extension kernel data block
* @xflags: options of the extension that have been used
* @invert: whether option was used with !
* @nvals: number of results in uXX_multi
* @val: parsed result
+ * @udata: per-extension private scratch area
+ * (cf. xtables_{match,target}->udata_size)
*/
struct xt_option_call {
const char *arg, *ext_name;
struct xt_entry_target **target;
};
void *xt_entry;
+ void *udata;
};
/**
* @ext_name: name of extension currently being processed
- * @data: per-extension data block
+ * @data: per-extension (kernel) data block
+ * @udata: per-extension private scratch area
+ * (cf. xtables_{match,target}->udata_size)
* @xflags: options of the extension that have been used
*/
struct xt_fcheck_call {
const char *ext_name;
- void *data;
+ void *data, *udata;
unsigned int xflags;
};
void (*x6_fcheck)(struct xt_fcheck_call *);
const struct xt_option_entry *x6_options;
+ /* Size of per-extension instance extra "global" scratch space */
+ size_t udata_size;
+
/* Ignore these men behind the curtain: */
+ void *udata;
unsigned int option_offset;
struct xt_entry_match *m;
unsigned int mflags;
void (*x6_fcheck)(struct xt_fcheck_call *);
const struct xt_option_entry *x6_options;
+ size_t udata_size;
+
/* Ignore these men behind the curtain: */
+ void *udata;
unsigned int option_offset;
struct xt_entry_target *t;
unsigned int tflags;
void xs_init_target(struct xtables_target *target)
{
+ if (target->udata_size != 0) {
+ free(target->udata);
+ target->udata = calloc(1, target->udata_size);
+ if (target->udata == NULL)
+ xtables_error(RESOURCE_PROBLEM, "malloc");
+ }
if (target->init != NULL)
target->init(target->t);
}
void xs_init_match(struct xtables_match *match)
{
+ if (match->udata_size != 0) {
+ /*
+ * As soon as a subsequent instance of the same match
+ * is used, e.g. "-m time -m time", the first instance
+ * is no longer reachable anyway, so we can free udata.
+ * Same goes for target.
+ */
+ free(match->udata);
+ match->udata = calloc(1, match->udata_size);
+ if (match->udata == NULL)
+ xtables_error(RESOURCE_PROBLEM, "malloc");
+ }
if (match->init != NULL)
match->init(match->m);
}