Skip to content

Commit

Permalink
netfilter: xtables: move extension arguments into compound structure …
Browse files Browse the repository at this point in the history
…(5/6)

This patch does this for target extensions' checkentry functions.

Signed-off-by: Jan Engelhardt <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>
  • Loading branch information
Jan Engelhardt authored and kaber committed Oct 8, 2008
1 parent 7eb3558 commit af5d6dc
Show file tree
Hide file tree
Showing 39 changed files with 208 additions and 283 deletions.
29 changes: 20 additions & 9 deletions include/linux/netfilter/x_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,23 @@ struct xt_target_param {
const void *targinfo;
};

/**
* struct xt_tgchk_param - parameters for target extensions'
* checkentry functions
*
* @entryinfo: the family-specific rule data
* (struct ipt_entry, ip6t_entry, arpt_entry, ebt_entry)
*
* Other fields see above.
*/
struct xt_tgchk_param {
const char *table;
void *entryinfo;
const struct xt_target *target;
void *targinfo;
unsigned int hook_mask;
};

struct xt_match
{
struct list_head list;
Expand Down Expand Up @@ -291,11 +308,7 @@ struct xt_target
hook_mask is a bitmask of hooks from which it can be
called. */
/* Should return true or false. */
bool (*checkentry)(const char *tablename,
const void *entry,
const struct xt_target *target,
void *targinfo,
unsigned int hook_mask);
bool (*checkentry)(const struct xt_tgchk_param *);

/* Called when entry of this type deleted. */
void (*destroy)(const struct xt_target *target, void *targinfo);
Expand Down Expand Up @@ -376,10 +389,8 @@ extern void xt_unregister_matches(struct xt_match *match, unsigned int n);

extern int xt_check_match(struct xt_mtchk_param *, u_int8_t family,
unsigned int size, u_int8_t proto, bool inv_proto);
extern int xt_check_target(const struct xt_target *target, unsigned short family,
unsigned int size, const char *table, unsigned int hook,
unsigned short proto, int inv_proto,
const void *entry, void *targinfo);
extern int xt_check_target(struct xt_tgchk_param *, u_int8_t family,
unsigned int size, u_int8_t proto, bool inv_proto);

extern struct xt_table *xt_register_table(struct net *net,
struct xt_table *table,
Expand Down
4 changes: 2 additions & 2 deletions include/linux/netfilter_bridge/ebtables.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,9 @@ extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
#define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg))
/* True if the hook mask denotes that the rule is in a base chain,
* used in the check() functions */
#define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS))
#define BASE_CHAIN (par->hook_mask & (1 << NF_BR_NUMHOOKS))
/* Clear the bit in the hook mask that tells if the rule is on a base chain */
#define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS))
#define CLEAR_BASE_CHAIN_BIT (par->hook_mask &= ~(1 << NF_BR_NUMHOOKS))
/* True if the target is not a standard target */
#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)

Expand Down
10 changes: 3 additions & 7 deletions net/bridge/netfilter/ebt_arpreply.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,16 @@ ebt_arpreply_tg(struct sk_buff *skb, const struct xt_target_param *par)
return info->target;
}

static bool
ebt_arpreply_tg_check(const char *tablename, const void *entry,
const struct xt_target *target, void *data,
unsigned int hookmask)
static bool ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
{
const struct ebt_arpreply_info *info = data;
const struct ebt_entry *e = entry;
const struct ebt_arpreply_info *info = par->targinfo;
const struct ebt_entry *e = par->entryinfo;

if (BASE_CHAIN && info->target == EBT_RETURN)
return false;
if (e->ethproto != htons(ETH_P_ARP) ||
e->invflags & EBT_IPROTO)
return false;
CLEAR_BASE_CHAIN_BIT;
return true;
}

Expand Down
19 changes: 10 additions & 9 deletions net/bridge/netfilter/ebt_dnat.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,20 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_target_param *par)
return info->target;
}

static bool
ebt_dnat_tg_check(const char *tablename, const void *entry,
const struct xt_target *target, void *data,
unsigned int hookmask)
static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par)
{
const struct ebt_nat_info *info = data;
const struct ebt_nat_info *info = par->targinfo;
unsigned int hook_mask;

if (BASE_CHAIN && info->target == EBT_RETURN)
return false;
CLEAR_BASE_CHAIN_BIT;
if ( (strcmp(tablename, "nat") ||
(hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) &&
(strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )

hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
if ((strcmp(par->table, "nat") != 0 ||
(hook_mask & ~((1 << NF_BR_PRE_ROUTING) |
(1 << NF_BR_LOCAL_OUT)))) &&
(strcmp(par->table, "broute") != 0 ||
hook_mask & ~(1 << NF_BR_BROUTING)))
return false;
if (INVALID_TARGET)
return false;
Expand Down
7 changes: 2 additions & 5 deletions net/bridge/netfilter/ebt_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@

static DEFINE_SPINLOCK(ebt_log_lock);

static bool
ebt_log_tg_check(const char *table, const void *entry,
const struct xt_target *target, void *data,
unsigned int hook_mask)
static bool ebt_log_tg_check(const struct xt_tgchk_param *par)
{
struct ebt_log_info *info = data;
struct ebt_log_info *info = par->targinfo;

if (info->bitmask & ~EBT_LOG_MASK)
return false;
Expand Down
8 changes: 2 additions & 6 deletions net/bridge/netfilter/ebt_mark.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,14 @@ ebt_mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
return info->target | ~EBT_VERDICT_BITS;
}

static bool
ebt_mark_tg_check(const char *table, const void *e,
const struct xt_target *target, void *data,
unsigned int hookmask)
static bool ebt_mark_tg_check(const struct xt_tgchk_param *par)
{
const struct ebt_mark_t_info *info = data;
const struct ebt_mark_t_info *info = par->targinfo;
int tmp;

tmp = info->target | ~EBT_VERDICT_BITS;
if (BASE_CHAIN && tmp == EBT_RETURN)
return false;
CLEAR_BASE_CHAIN_BIT;
if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
return false;
tmp = info->target & ~EBT_VERDICT_BITS;
Expand Down
7 changes: 2 additions & 5 deletions net/bridge/netfilter/ebt_nflog.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,9 @@ ebt_nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
return EBT_CONTINUE;
}

static bool
ebt_nflog_tg_check(const char *table, const void *e,
const struct xt_target *target, void *data,
unsigned int hookmask)
static bool ebt_nflog_tg_check(const struct xt_tgchk_param *par)
{
struct ebt_nflog_info *info = data;
struct ebt_nflog_info *info = par->targinfo;

if (info->flags & ~EBT_NFLOG_MASK)
return false;
Expand Down
17 changes: 9 additions & 8 deletions net/bridge/netfilter/ebt_redirect.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,19 @@ ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
return info->target;
}

static bool
ebt_redirect_tg_check(const char *tablename, const void *e,
const struct xt_target *target, void *data,
unsigned int hookmask)
static bool ebt_redirect_tg_check(const struct xt_tgchk_param *par)
{
const struct ebt_redirect_info *info = data;
const struct ebt_redirect_info *info = par->targinfo;
unsigned int hook_mask;

if (BASE_CHAIN && info->target == EBT_RETURN)
return false;
CLEAR_BASE_CHAIN_BIT;
if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) &&
(strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )

hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
if ((strcmp(par->table, "nat") != 0 ||
hook_mask & ~(1 << NF_BR_PRE_ROUTING)) &&
(strcmp(par->table, "broute") != 0 ||
hook_mask & ~(1 << NF_BR_BROUTING)))
return false;
if (INVALID_TARGET)
return false;
Expand Down
8 changes: 2 additions & 6 deletions net/bridge/netfilter/ebt_snat.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,14 @@ ebt_snat_tg(struct sk_buff *skb, const struct xt_target_param *par)
return info->target | ~EBT_VERDICT_BITS;
}

static bool
ebt_snat_tg_check(const char *tablename, const void *e,
const struct xt_target *target, void *data,
unsigned int hookmask)
static bool ebt_snat_tg_check(const struct xt_tgchk_param *par)
{
const struct ebt_nat_info *info = data;
const struct ebt_nat_info *info = par->targinfo;
int tmp;

tmp = info->target | ~EBT_VERDICT_BITS;
if (BASE_CHAIN && tmp == EBT_RETURN)
return false;
CLEAR_BASE_CHAIN_BIT;

if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
return false;
Expand Down
7 changes: 2 additions & 5 deletions net/bridge/netfilter/ebt_ulog.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,9 @@ ebt_ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
return EBT_CONTINUE;
}

static bool
ebt_ulog_tg_check(const char *table, const void *entry,
const struct xt_target *target, void *data,
unsigned int hookmask)
static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
{
struct ebt_ulog_info *uloginfo = data;
struct ebt_ulog_info *uloginfo = par->targinfo;

if (uloginfo->nlgroup > 31)
return false;
Expand Down
28 changes: 16 additions & 12 deletions net/bridge/netfilter/ebtables.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,10 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,
}

static inline int
ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
const char *name, unsigned int hookmask, unsigned int *cnt)
ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,
unsigned int *cnt)
{
const struct ebt_entry *e = par->entryinfo;
struct xt_target *watcher;
size_t left = ((char *)e + e->target_offset) - (char *)w;
int ret;
Expand All @@ -383,9 +384,10 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
return -ENOENT;
w->u.watcher = watcher;

ret = xt_check_target(watcher, NFPROTO_BRIDGE, w->watcher_size,
name, hookmask, e->ethproto, e->invflags & EBT_IPROTO,
e, w->data);
par->target = watcher;
par->targinfo = w->data;
ret = xt_check_target(par, NFPROTO_BRIDGE, w->watcher_size,
e->ethproto, e->invflags & EBT_IPROTO);
if (ret < 0) {
module_put(watcher->me);
return ret;
Expand Down Expand Up @@ -619,6 +621,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
size_t gap;
int ret;
struct xt_mtchk_param mtpar;
struct xt_tgchk_param tgpar;

/* don't mess with the struct ebt_entries */
if (e->bitmask == 0)
Expand Down Expand Up @@ -660,14 +663,14 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
}
i = 0;

mtpar.table = name;
mtpar.entryinfo = e;
mtpar.hook_mask = hookmask;
mtpar.table = tgpar.table = name;
mtpar.entryinfo = tgpar.entryinfo = e;
mtpar.hook_mask = tgpar.hook_mask = hookmask;
ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i);
if (ret != 0)
goto cleanup_matches;
j = 0;
ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j);
ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, &tgpar, &j);
if (ret != 0)
goto cleanup_watchers;
t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
Expand Down Expand Up @@ -703,9 +706,10 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
goto cleanup_watchers;
}

ret = xt_check_target(target, NFPROTO_BRIDGE, t->target_size,
name, hookmask, e->ethproto, e->invflags & EBT_IPROTO,
e, t->data);
tgpar.target = target;
tgpar.targinfo = t->data;
ret = xt_check_target(&tgpar, NFPROTO_BRIDGE, t->target_size,
e->ethproto, e->invflags & EBT_IPROTO);
if (ret < 0) {
module_put(target->me);
goto cleanup_watchers;
Expand Down
20 changes: 11 additions & 9 deletions net/ipv4/netfilter/arp_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,16 +457,18 @@ static inline int check_entry(struct arpt_entry *e, const char *name)

static inline int check_target(struct arpt_entry *e, const char *name)
{
struct arpt_entry_target *t;
struct xt_target *target;
struct arpt_entry_target *t = arpt_get_target(e);
int ret;

t = arpt_get_target(e);
target = t->u.kernel.target;

ret = xt_check_target(target, NFPROTO_ARP,
t->u.target_size - sizeof(*t),
name, e->comefrom, 0, 0, e, t->data);
struct xt_tgchk_param par = {
.table = name,
.entryinfo = e,
.target = t->u.kernel.target,
.targinfo = t->data,
.hook_mask = e->comefrom,
};

ret = xt_check_target(&par, NFPROTO_ARP,
t->u.target_size - sizeof(*t), 0, false);
if (ret < 0) {
duprintf("arp_tables: check failed for `%s'.\n",
t->u.kernel.target->name);
Expand Down
6 changes: 2 additions & 4 deletions net/ipv4/netfilter/arpt_mangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,9 @@ target(struct sk_buff *skb, const struct xt_target_param *par)
return mangle->target;
}

static bool
checkentry(const char *tablename, const void *e, const struct xt_target *target,
void *targinfo, unsigned int hook_mask)
static bool checkentry(const struct xt_tgchk_param *par)
{
const struct arpt_mangle *mangle = targinfo;
const struct arpt_mangle *mangle = par->targinfo;

if (mangle->flags & ~ARPT_MANGLE_MASK ||
!(mangle->flags & ARPT_MANGLE_MASK))
Expand Down
17 changes: 10 additions & 7 deletions net/ipv4/netfilter/ip_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,15 +655,18 @@ find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,

static int check_target(struct ipt_entry *e, const char *name)
{
struct ipt_entry_target *t;
struct xt_target *target;
struct ipt_entry_target *t = ipt_get_target(e);
struct xt_tgchk_param par = {
.table = name,
.entryinfo = e,
.target = t->u.kernel.target,
.targinfo = t->data,
.hook_mask = e->comefrom,
};
int ret;

t = ipt_get_target(e);
target = t->u.kernel.target;
ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
name, e->comefrom, e->ip.proto,
e->ip.invflags & IPT_INV_PROTO, e, t->data);
ret = xt_check_target(&par, NFPROTO_IPV4, t->u.target_size - sizeof(*t),
e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n",
t->u.kernel.target->name);
Expand Down
13 changes: 5 additions & 8 deletions net/ipv4/netfilter/ipt_CLUSTERIP.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,10 @@ clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par)
return XT_CONTINUE;
}

static bool
clusterip_tg_check(const char *tablename, const void *e_void,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool clusterip_tg_check(const struct xt_tgchk_param *par)
{
struct ipt_clusterip_tgt_info *cipinfo = targinfo;
const struct ipt_entry *e = e_void;
struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
const struct ipt_entry *e = par->entryinfo;

struct clusterip_config *config;

Expand Down Expand Up @@ -404,9 +401,9 @@ clusterip_tg_check(const char *tablename, const void *e_void,
}
cipinfo->config = config;

if (nf_ct_l3proto_try_module_get(target->family) < 0) {
if (nf_ct_l3proto_try_module_get(par->target->family) < 0) {
printk(KERN_WARNING "can't load conntrack support for "
"proto=%u\n", target->family);
"proto=%u\n", par->target->family);
return false;
}

Expand Down
Loading

0 comments on commit af5d6dc

Please sign in to comment.