Skip to content

Commit

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

This patch does this for match extensions' checkentry functions.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
  • Loading branch information
Jan Engelhardt authored and kaber committed Oct 8, 2008
1 parent f7108a2 commit 9b4fce7
Show file tree
Hide file tree
Showing 48 changed files with 240 additions and 386 deletions.
32 changes: 22 additions & 10 deletions include/linux/netfilter/x_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,25 @@ struct xt_match_param {
bool *hotdrop;
};

/**
* struct xt_mtchk_param - parameters for match extensions'
* checkentry functions
*
* @table: table the rule is tried to be inserted into
* @entryinfo: the family-specific rule data
* (struct ipt_ip, ip6t_ip, ebt_entry)
* @match: struct xt_match through which this function was invoked
* @matchinfo: per-match data
* @hook_mask: via which hooks the new rule is reachable
*/
struct xt_mtchk_param {
const char *table;
const void *entryinfo;
const struct xt_match *match;
void *matchinfo;
unsigned int hook_mask;
};

struct xt_match
{
struct list_head list;
Expand All @@ -208,12 +227,7 @@ struct xt_match
const struct xt_match_param *);

/* Called when user tries to insert an entry of this type. */
/* Should return true or false. */
bool (*checkentry)(const char *tablename,
const void *ip,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask);
bool (*checkentry)(const struct xt_mtchk_param *);

/* Called when entry of this type deleted. */
void (*destroy)(const struct xt_match *match, void *matchinfo);
Expand Down Expand Up @@ -342,10 +356,8 @@ extern void xt_unregister_match(struct xt_match *target);
extern int xt_register_matches(struct xt_match *match, unsigned int n);
extern void xt_unregister_matches(struct xt_match *match, unsigned int n);

extern int xt_check_match(const struct xt_match *match, unsigned short family,
unsigned int size, const char *table, unsigned int hook,
unsigned short proto, int inv_proto,
const void *entry, void *matchinfo);
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,
Expand Down
7 changes: 2 additions & 5 deletions net/bridge/netfilter/ebt_802_3.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,9 @@ ebt_802_3_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true;
}

static bool
ebt_802_3_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_802_3_info *info = data;
const struct ebt_802_3_info *info = par->matchinfo;

if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK)
return false;
Expand Down
9 changes: 3 additions & 6 deletions net/bridge/netfilter/ebt_among.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,11 @@ ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true;
}

static bool
ebt_among_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
static bool ebt_among_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_among_info *info = par->matchinfo;
const struct ebt_entry_match *em =
container_of(data, const struct ebt_entry_match, data);
const struct ebt_among_info *info = data;
container_of(par->matchinfo, const struct ebt_entry_match, data);
int expected_length = sizeof(struct ebt_among_info);
const struct ebt_mac_wormhash *wh_dst, *wh_src;
int err;
Expand Down
9 changes: 3 additions & 6 deletions net/bridge/netfilter/ebt_arp.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,10 @@ ebt_arp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true;
}

static bool
ebt_arp_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
static bool ebt_arp_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_arp_info *info = data;
const struct ebt_entry *e = entry;
const struct ebt_arp_info *info = par->matchinfo;
const struct ebt_entry *e = par->entryinfo;

if ((e->ethproto != htons(ETH_P_ARP) &&
e->ethproto != htons(ETH_P_RARP)) ||
Expand Down
9 changes: 3 additions & 6 deletions net/bridge/netfilter/ebt_ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,10 @@ ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true;
}

static bool
ebt_ip_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
static bool ebt_ip_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_ip_info *info = data;
const struct ebt_entry *e = entry;
const struct ebt_ip_info *info = par->matchinfo;
const struct ebt_entry *e = par->entryinfo;

if (e->ethproto != htons(ETH_P_IP) ||
e->invflags & EBT_IPROTO)
Expand Down
9 changes: 3 additions & 6 deletions net/bridge/netfilter/ebt_ip6.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,10 @@ ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true;
}

static bool
ebt_ip6_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
static bool ebt_ip6_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_entry *e = entry;
struct ebt_ip6_info *info = data;
const struct ebt_entry *e = par->entryinfo;
struct ebt_ip6_info *info = par->matchinfo;

if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO)
return false;
Expand Down
7 changes: 2 additions & 5 deletions net/bridge/netfilter/ebt_limit.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,9 @@ user2credits(u_int32_t user)
return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE;
}

static bool
ebt_limit_mt_check(const char *table, const void *e,
const struct xt_match *match, void *data,
unsigned int hook_mask)
static bool ebt_limit_mt_check(const struct xt_mtchk_param *par)
{
struct ebt_limit_info *info = data;
struct ebt_limit_info *info = par->matchinfo;

/* Check for overflow. */
if (info->burst == 0 ||
Expand Down
7 changes: 2 additions & 5 deletions net/bridge/netfilter/ebt_mark_m.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,9 @@ ebt_mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return ((skb->mark & info->mask) == info->mark) ^ info->invert;
}

static bool
ebt_mark_mt_check(const char *table, const void *e,
const struct xt_match *match, void *data,
unsigned int hook_mask)
static bool ebt_mark_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_mark_m_info *info = data;
const struct ebt_mark_m_info *info = par->matchinfo;

if (info->bitmask & ~EBT_MARK_MASK)
return false;
Expand Down
7 changes: 2 additions & 5 deletions net/bridge/netfilter/ebt_pkttype.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,9 @@ ebt_pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return (skb->pkt_type == info->pkt_type) ^ info->invert;
}

static bool
ebt_pkttype_mt_check(const char *table, const void *e,
const struct xt_match *match, void *data,
unsigned int hook_mask)
static bool ebt_pkttype_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_pkttype_info *info = data;
const struct ebt_pkttype_info *info = par->matchinfo;

if (info->invert != 0 && info->invert != 1)
return false;
Expand Down
9 changes: 3 additions & 6 deletions net/bridge/netfilter/ebt_stp.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,12 @@ ebt_stp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true;
}

static bool
ebt_stp_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
static bool ebt_stp_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_stp_info *info = data;
const struct ebt_stp_info *info = par->matchinfo;
const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const struct ebt_entry *e = entry;
const struct ebt_entry *e = par->entryinfo;

if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
!(info->bitmask & EBT_STP_MASK))
Expand Down
9 changes: 3 additions & 6 deletions net/bridge/netfilter/ebt_vlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,10 @@ ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true;
}

static bool
ebt_vlan_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
{
struct ebt_vlan_info *info = data;
const struct ebt_entry *e = entry;
struct ebt_vlan_info *info = par->matchinfo;
const struct ebt_entry *e = par->entryinfo;

/* Is it 802.1Q frame checked? */
if (e->ethproto != htons(ETH_P_8021Q)) {
Expand Down
19 changes: 13 additions & 6 deletions net/bridge/netfilter/ebtables.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,10 @@ find_table_lock(const char *name, int *error, struct mutex *mutex)
}

static inline int
ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
const char *name, unsigned int hookmask, unsigned int *cnt)
ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,
unsigned int *cnt)
{
const struct ebt_entry *e = par->entryinfo;
struct xt_match *match;
size_t left = ((char *)e + e->watchers_offset) - (char *)m;
int ret;
Expand All @@ -343,9 +344,10 @@ ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
return -ENOENT;
m->u.match = match;

ret = xt_check_match(match, NFPROTO_BRIDGE, m->match_size,
name, hookmask, e->ethproto, e->invflags & EBT_IPROTO,
e, m->data);
par->match = match;
par->matchinfo = m->data;
ret = xt_check_match(par, NFPROTO_BRIDGE, m->match_size,
e->ethproto, e->invflags & EBT_IPROTO);
if (ret < 0) {
module_put(match->me);
return ret;
Expand Down Expand Up @@ -607,6 +609,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
unsigned int i, j, hook = 0, hookmask = 0;
size_t gap;
int ret;
struct xt_mtchk_param par;

/* don't mess with the struct ebt_entries */
if (e->bitmask == 0)
Expand Down Expand Up @@ -647,7 +650,11 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
hookmask = cl_s[i - 1].hookmask;
}
i = 0;
ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i);

par.table = name;
par.entryinfo = e;
par.hook_mask = hookmask;
ret = EBT_MATCH_ITERATE(e, ebt_check_match, &par, &i);
if (ret != 0)
goto cleanup_matches;
j = 0;
Expand Down
49 changes: 23 additions & 26 deletions net/ipv4/netfilter/ip_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,31 +607,28 @@ check_entry(struct ipt_entry *e, const char *name)
}

static int
check_match(struct ipt_entry_match *m, const char *name,
const struct ipt_ip *ip,
unsigned int hookmask, unsigned int *i)
check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
unsigned int *i)
{
struct xt_match *match;
const struct ipt_ip *ip = par->entryinfo;
int ret;

match = m->u.kernel.match;
ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m),
name, hookmask, ip->proto,
ip->invflags & IPT_INV_PROTO, ip, m->data);
par->match = m->u.kernel.match;
par->matchinfo = m->data;

ret = xt_check_match(par, NFPROTO_IPV4, m->u.match_size - sizeof(*m),
ip->proto, ip->invflags & IPT_INV_PROTO);
if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n",
m->u.kernel.match->name);
par.match->name);
return ret;
}
++*i;
return 0;
}

static int
find_check_match(struct ipt_entry_match *m,
const char *name,
const struct ipt_ip *ip,
unsigned int hookmask,
find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
unsigned int *i)
{
struct xt_match *match;
Expand All @@ -646,7 +643,7 @@ find_check_match(struct ipt_entry_match *m,
}
m->u.kernel.match = match;

ret = check_match(m, name, ip, hookmask, i);
ret = check_match(m, par, i);
if (ret)
goto err;

Expand Down Expand Up @@ -683,14 +680,17 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
struct xt_target *target;
int ret;
unsigned int j;
struct xt_mtchk_param mtpar;

ret = check_entry(e, name);
if (ret)
return ret;

j = 0;
ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip,
e->comefrom, &j);
mtpar.table = name;
mtpar.entryinfo = &e->ip;
mtpar.hook_mask = e->comefrom;
ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
if (ret != 0)
goto cleanup_matches;

Expand Down Expand Up @@ -1644,12 +1644,15 @@ static int
compat_check_entry(struct ipt_entry *e, const char *name,
unsigned int *i)
{
struct xt_mtchk_param mtpar;
unsigned int j;
int ret;

j = 0;
ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip,
e->comefrom, &j);
mtpar.table = name;
mtpar.entryinfo = &e->ip;
mtpar.hook_mask = e->comefrom;
ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
if (ret)
goto cleanup_matches;

Expand Down Expand Up @@ -2144,15 +2147,9 @@ icmp_match(const struct sk_buff *skb, const struct xt_match_param *par)
!!(icmpinfo->invflags&IPT_ICMP_INV));
}

/* Called when user tries to insert an entry of this type. */
static bool
icmp_checkentry(const char *tablename,
const void *entry,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask)
static bool icmp_checkentry(const struct xt_mtchk_param *par)
{
const struct ipt_icmp *icmpinfo = matchinfo;
const struct ipt_icmp *icmpinfo = par->matchinfo;

/* Must specify no unknown invflags */
return !(icmpinfo->invflags & ~IPT_ICMP_INV);
Expand Down
Loading

0 comments on commit 9b4fce7

Please sign in to comment.