Commit 9b4fce7a authored by Jan Engelhardt's avatar Jan Engelhardt Committed by Patrick McHardy

netfilter: xtables: move extension arguments into compound structure (2/6)

This patch does this for match extensions' checkentry functions.
Signed-off-by: default avatarJan Engelhardt <jengelh@medozas.de>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent f7108a20
...@@ -193,6 +193,25 @@ struct xt_match_param { ...@@ -193,6 +193,25 @@ struct xt_match_param {
bool *hotdrop; 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 xt_match
{ {
struct list_head list; struct list_head list;
...@@ -208,12 +227,7 @@ struct xt_match ...@@ -208,12 +227,7 @@ struct xt_match
const struct xt_match_param *); const struct xt_match_param *);
/* Called when user tries to insert an entry of this type. */ /* Called when user tries to insert an entry of this type. */
/* Should return true or false. */ bool (*checkentry)(const struct xt_mtchk_param *);
bool (*checkentry)(const char *tablename,
const void *ip,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask);
/* Called when entry of this type deleted. */ /* Called when entry of this type deleted. */
void (*destroy)(const struct xt_match *match, void *matchinfo); void (*destroy)(const struct xt_match *match, void *matchinfo);
...@@ -342,10 +356,8 @@ extern void xt_unregister_match(struct xt_match *target); ...@@ -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 int xt_register_matches(struct xt_match *match, unsigned int n);
extern void xt_unregister_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, extern int xt_check_match(struct xt_mtchk_param *, u_int8_t family,
unsigned int size, const char *table, unsigned int hook, unsigned int size, u_int8_t proto, bool inv_proto);
unsigned short proto, int inv_proto,
const void *entry, void *matchinfo);
extern int xt_check_target(const struct xt_target *target, unsigned short family, extern int xt_check_target(const struct xt_target *target, unsigned short family,
unsigned int size, const char *table, unsigned int hook, unsigned int size, const char *table, unsigned int hook,
unsigned short proto, int inv_proto, unsigned short proto, int inv_proto,
......
...@@ -36,12 +36,9 @@ ebt_802_3_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -36,12 +36,9 @@ ebt_802_3_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par)
ebt_802_3_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
{ {
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) if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK)
return false; return false;
......
...@@ -171,14 +171,11 @@ ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -171,14 +171,11 @@ ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool static bool ebt_among_mt_check(const struct xt_mtchk_param *par)
ebt_among_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
{ {
const struct ebt_among_info *info = par->matchinfo;
const struct ebt_entry_match *em = const struct ebt_entry_match *em =
container_of(data, const struct ebt_entry_match, data); container_of(par->matchinfo, const struct ebt_entry_match, data);
const struct ebt_among_info *info = data;
int expected_length = sizeof(struct ebt_among_info); int expected_length = sizeof(struct ebt_among_info);
const struct ebt_mac_wormhash *wh_dst, *wh_src; const struct ebt_mac_wormhash *wh_dst, *wh_src;
int err; int err;
......
...@@ -100,13 +100,10 @@ ebt_arp_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -100,13 +100,10 @@ ebt_arp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool static bool ebt_arp_mt_check(const struct xt_mtchk_param *par)
ebt_arp_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
{ {
const struct ebt_arp_info *info = data; const struct ebt_arp_info *info = par->matchinfo;
const struct ebt_entry *e = entry; const struct ebt_entry *e = par->entryinfo;
if ((e->ethproto != htons(ETH_P_ARP) && if ((e->ethproto != htons(ETH_P_ARP) &&
e->ethproto != htons(ETH_P_RARP)) || e->ethproto != htons(ETH_P_RARP)) ||
......
...@@ -77,13 +77,10 @@ ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -77,13 +77,10 @@ ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool static bool ebt_ip_mt_check(const struct xt_mtchk_param *par)
ebt_ip_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
{ {
const struct ebt_ip_info *info = data; const struct ebt_ip_info *info = par->matchinfo;
const struct ebt_entry *e = entry; const struct ebt_entry *e = par->entryinfo;
if (e->ethproto != htons(ETH_P_IP) || if (e->ethproto != htons(ETH_P_IP) ||
e->invflags & EBT_IPROTO) e->invflags & EBT_IPROTO)
......
...@@ -90,13 +90,10 @@ ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -90,13 +90,10 @@ ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool static bool ebt_ip6_mt_check(const struct xt_mtchk_param *par)
ebt_ip6_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
{ {
const struct ebt_entry *e = entry; const struct ebt_entry *e = par->entryinfo;
struct ebt_ip6_info *info = data; struct ebt_ip6_info *info = par->matchinfo;
if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO) if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO)
return false; return false;
......
...@@ -64,12 +64,9 @@ user2credits(u_int32_t user) ...@@ -64,12 +64,9 @@ user2credits(u_int32_t user)
return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE; return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE;
} }
static bool static bool ebt_limit_mt_check(const struct xt_mtchk_param *par)
ebt_limit_mt_check(const char *table, const void *e,
const struct xt_match *match, void *data,
unsigned int hook_mask)
{ {
struct ebt_limit_info *info = data; struct ebt_limit_info *info = par->matchinfo;
/* Check for overflow. */ /* Check for overflow. */
if (info->burst == 0 || if (info->burst == 0 ||
......
...@@ -22,12 +22,9 @@ ebt_mark_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -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; return ((skb->mark & info->mask) == info->mark) ^ info->invert;
} }
static bool static bool ebt_mark_mt_check(const struct xt_mtchk_param *par)
ebt_mark_mt_check(const char *table, const void *e,
const struct xt_match *match, void *data,
unsigned int hook_mask)
{ {
const struct ebt_mark_m_info *info = data; const struct ebt_mark_m_info *info = par->matchinfo;
if (info->bitmask & ~EBT_MARK_MASK) if (info->bitmask & ~EBT_MARK_MASK)
return false; return false;
......
...@@ -20,12 +20,9 @@ ebt_pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -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; return (skb->pkt_type == info->pkt_type) ^ info->invert;
} }
static bool static bool ebt_pkttype_mt_check(const struct xt_mtchk_param *par)
ebt_pkttype_mt_check(const char *table, const void *e,
const struct xt_match *match, void *data,
unsigned int hook_mask)
{ {
const struct ebt_pkttype_info *info = data; const struct ebt_pkttype_info *info = par->matchinfo;
if (info->invert != 0 && info->invert != 1) if (info->invert != 0 && info->invert != 1)
return false; return false;
......
...@@ -153,15 +153,12 @@ ebt_stp_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -153,15 +153,12 @@ ebt_stp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool static bool ebt_stp_mt_check(const struct xt_mtchk_param *par)
ebt_stp_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
{ {
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 bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 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 || if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
!(info->bitmask & EBT_STP_MASK)) !(info->bitmask & EBT_STP_MASK))
......
...@@ -84,13 +84,10 @@ ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -84,13 +84,10 @@ ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
ebt_vlan_mt_check(const char *table, const void *entry,
const struct xt_match *match, void *data,
unsigned int hook_mask)
{ {
struct ebt_vlan_info *info = data; struct ebt_vlan_info *info = par->matchinfo;
const struct ebt_entry *e = entry; const struct ebt_entry *e = par->entryinfo;
/* Is it 802.1Q frame checked? */ /* Is it 802.1Q frame checked? */
if (e->ethproto != htons(ETH_P_8021Q)) { if (e->ethproto != htons(ETH_P_8021Q)) {
......
...@@ -324,9 +324,10 @@ find_table_lock(const char *name, int *error, struct mutex *mutex) ...@@ -324,9 +324,10 @@ find_table_lock(const char *name, int *error, struct mutex *mutex)
} }
static inline int static inline int
ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,
const char *name, unsigned int hookmask, unsigned int *cnt) unsigned int *cnt)
{ {
const struct ebt_entry *e = par->entryinfo;
struct xt_match *match; struct xt_match *match;
size_t left = ((char *)e + e->watchers_offset) - (char *)m; size_t left = ((char *)e + e->watchers_offset) - (char *)m;
int ret; int ret;
...@@ -343,9 +344,10 @@ ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, ...@@ -343,9 +344,10 @@ ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
return -ENOENT; return -ENOENT;
m->u.match = match; m->u.match = match;
ret = xt_check_match(match, NFPROTO_BRIDGE, m->match_size, par->match = match;
name, hookmask, e->ethproto, e->invflags & EBT_IPROTO, par->matchinfo = m->data;
e, m->data); ret = xt_check_match(par, NFPROTO_BRIDGE, m->match_size,
e->ethproto, e->invflags & EBT_IPROTO);
if (ret < 0) { if (ret < 0) {
module_put(match->me); module_put(match->me);
return ret; return ret;
...@@ -607,6 +609,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, ...@@ -607,6 +609,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
unsigned int i, j, hook = 0, hookmask = 0; unsigned int i, j, hook = 0, hookmask = 0;
size_t gap; size_t gap;
int ret; int ret;
struct xt_mtchk_param par;
/* don't mess with the struct ebt_entries */ /* don't mess with the struct ebt_entries */
if (e->bitmask == 0) if (e->bitmask == 0)
...@@ -647,7 +650,11 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, ...@@ -647,7 +650,11 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
hookmask = cl_s[i - 1].hookmask; hookmask = cl_s[i - 1].hookmask;
} }
i = 0; 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) if (ret != 0)
goto cleanup_matches; goto cleanup_matches;
j = 0; j = 0;
......
...@@ -607,20 +607,20 @@ check_entry(struct ipt_entry *e, const char *name) ...@@ -607,20 +607,20 @@ check_entry(struct ipt_entry *e, const char *name)
} }
static int static int
check_match(struct ipt_entry_match *m, const char *name, check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
const struct ipt_ip *ip, unsigned int *i)
unsigned int hookmask, unsigned int *i)
{ {
struct xt_match *match; const struct ipt_ip *ip = par->entryinfo;
int ret; int ret;
match = m->u.kernel.match; par->match = m->u.kernel.match;
ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m), par->matchinfo = m->data;
name, hookmask, ip->proto,
ip->invflags & IPT_INV_PROTO, ip, 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) { if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n", duprintf("ip_tables: check failed for `%s'.\n",
m->u.kernel.match->name); par.match->name);
return ret; return ret;
} }
++*i; ++*i;
...@@ -628,10 +628,7 @@ check_match(struct ipt_entry_match *m, const char *name, ...@@ -628,10 +628,7 @@ check_match(struct ipt_entry_match *m, const char *name,
} }
static int static int
find_check_match(struct ipt_entry_match *m, find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
const char *name,
const struct ipt_ip *ip,
unsigned int hookmask,
unsigned int *i) unsigned int *i)
{ {
struct xt_match *match; struct xt_match *match;
...@@ -646,7 +643,7 @@ find_check_match(struct ipt_entry_match *m, ...@@ -646,7 +643,7 @@ find_check_match(struct ipt_entry_match *m,
} }
m->u.kernel.match = match; m->u.kernel.match = match;
ret = check_match(m, name, ip, hookmask, i); ret = check_match(m, par, i);
if (ret) if (ret)
goto err; goto err;
...@@ -683,14 +680,17 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size, ...@@ -683,14 +680,17 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
struct xt_target *target; struct xt_target *target;
int ret; int ret;
unsigned int j; unsigned int j;
struct xt_mtchk_param mtpar;
ret = check_entry(e, name); ret = check_entry(e, name);
if (ret) if (ret)
return ret; return ret;
j = 0; j = 0;
ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip, mtpar.table = name;
e->comefrom, &j); mtpar.entryinfo = &e->ip;
mtpar.hook_mask = e->comefrom;
ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
if (ret != 0) if (ret != 0)
goto cleanup_matches; goto cleanup_matches;
...@@ -1644,12 +1644,15 @@ static int ...@@ -1644,12 +1644,15 @@ static int
compat_check_entry(struct ipt_entry *e, const char *name, compat_check_entry(struct ipt_entry *e, const char *name,
unsigned int *i) unsigned int *i)
{ {
struct xt_mtchk_param mtpar;
unsigned int j; unsigned int j;
int ret; int ret;
j = 0; j = 0;
ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, mtpar.table = name;
e->comefrom, &j); mtpar.entryinfo = &e->ip;
mtpar.hook_mask = e->comefrom;
ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
if (ret) if (ret)
goto cleanup_matches; goto cleanup_matches;
...@@ -2144,15 +2147,9 @@ icmp_match(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -2144,15 +2147,9 @@ icmp_match(const struct sk_buff *skb, const struct xt_match_param *par)
!!(icmpinfo->invflags&IPT_ICMP_INV)); !!(icmpinfo->invflags&IPT_ICMP_INV));
} }
/* Called when user tries to insert an entry of this type. */ static bool icmp_checkentry(const struct xt_mtchk_param *par)
static bool
icmp_checkentry(const char *tablename,
const void *entry,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask)
{ {
const struct ipt_icmp *icmpinfo = matchinfo; const struct ipt_icmp *icmpinfo = par->matchinfo;
/* Must specify no unknown invflags */ /* Must specify no unknown invflags */
return !(icmpinfo->invflags & ~IPT_ICMP_INV); return !(icmpinfo->invflags & ~IPT_ICMP_INV);
......
...@@ -68,12 +68,9 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -68,12 +68,9 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
return ret; return ret;
} }
static bool static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
struct ipt_addrtype_info_v1 *info = matchinfo; struct ipt_addrtype_info_v1 *info = par->matchinfo;
if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
...@@ -82,14 +79,16 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void, ...@@ -82,14 +79,16 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
return false; return false;
} }
if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) && if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_LOCAL_IN)) &&
info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
printk(KERN_ERR "ipt_addrtype: output interface limitation " printk(KERN_ERR "ipt_addrtype: output interface limitation "
"not valid in PRE_ROUTING and INPUT\n"); "not valid in PRE_ROUTING and INPUT\n");
return false; return false;
} }
if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) && if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
(1 << NF_INET_LOCAL_OUT)) &&
info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
printk(KERN_ERR "ipt_addrtype: input interface limitation " printk(KERN_ERR "ipt_addrtype: input interface limitation "
"not valid in POST_ROUTING and OUTPUT\n"); "not valid in POST_ROUTING and OUTPUT\n");
......
...@@ -61,13 +61,9 @@ static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -61,13 +61,9 @@ static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par)
!!(ahinfo->invflags & IPT_AH_INV_SPI)); !!(ahinfo->invflags & IPT_AH_INV_SPI));
} }
/* Called when user tries to insert an entry of this type. */ static bool ah_mt_check(const struct xt_mtchk_param *par)
static bool
ah_mt_check(const char *tablename, const void *ip_void,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ipt_ah *ahinfo = matchinfo; const struct ipt_ah *ahinfo = par->matchinfo;
/* Must specify no unknown invflags */ /* Must specify no unknown invflags */
if (ahinfo->invflags & ~IPT_AH_INV_MASK) { if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
......
...@@ -85,13 +85,10 @@ static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -85,13 +85,10 @@ static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool static bool ecn_mt_check(const struct xt_mtchk_param *par)
ecn_mt_check(const char *tablename, const void *ip_void,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ipt_ecn_info *info = matchinfo; const struct ipt_ecn_info *info = par->matchinfo;
const struct ipt_ip *ip = ip_void; const struct ipt_ip *ip = par->entryinfo;
if (info->operation & IPT_ECN_OP_MATCH_MASK) if (info->operation & IPT_ECN_OP_MATCH_MASK)
return false; return false;
......
...@@ -629,20 +629,20 @@ check_entry(struct ip6t_entry *e, const char *name) ...@@ -629,20 +629,20 @@ check_entry(struct ip6t_entry *e, const char *name)
return 0; return 0;
} }
static int check_match(struct ip6t_entry_match *m, const char *name, static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
const struct ip6t_ip6 *ipv6, unsigned int *i)
unsigned int hookmask, unsigned int *i)
{ {
struct xt_match *match; const struct ip6t_ip6 *ipv6 = par->entryinfo;
int ret; int ret;
match = m->u.kernel.match; par->match = m->u.kernel.match;
ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m), par->matchinfo = m->data;
name, hookmask, ipv6->proto,
ipv6->invflags & IP6T_INV_PROTO, ipv6, m->data); ret = xt_check_match(par, NFPROTO_IPV6, m->u.match_size - sizeof(*m),
ipv6->proto, ipv6->invflags & IP6T_INV_PROTO);
if (ret < 0) { if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n", duprintf("ip_tables: check failed for `%s'.\n",
m->u.kernel.match->name); par.match->name);
return ret; return ret;
} }
++*i; ++*i;
...@@ -650,10 +650,7 @@ static int check_match(struct ip6t_entry_match *m, const char *name, ...@@ -650,10 +650,7 @@ static int check_match(struct ip6t_entry_match *m, const char *name,
} }
static int static int
find_check_match(struct ip6t_entry_match *m, find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
const char *name,
const struct ip6t_ip6 *ipv6,
unsigned int hookmask,
unsigned int *i) unsigned int *i)
{ {
struct xt_match *match; struct xt_match *match;
...@@ -668,7 +665,7 @@ find_check_match(struct ip6t_entry_match *m, ...@@ -668,7 +665,7 @@ find_check_match(struct ip6t_entry_match *m,
} }
m->u.kernel.match = match; m->u.kernel.match = match;
ret = check_match(m, name, ipv6, hookmask, i); ret = check_match(m, par, i);
if (ret) if (ret)
goto err; goto err;
...@@ -705,14 +702,17 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size, ...@@ -705,14 +702,17 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
struct xt_target *target; struct xt_target *target;
int ret; int ret;
unsigned int j; unsigned int j;
struct xt_mtchk_param mtpar;
ret = check_entry(e, name); ret = check_entry(e, name);
if (ret) if (ret)
return ret; return ret;
j = 0; j = 0;
ret = IP6T_MATCH_ITERATE(e, find_check_match, name, &e->ipv6, mtpar.table = name;
e->comefrom, &j); mtpar.entryinfo = &e->ipv6;
mtpar.hook_mask = e->comefrom;
ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
if (ret != 0) if (ret != 0)
goto cleanup_matches; goto cleanup_matches;
...@@ -1669,10 +1669,13 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name, ...@@ -1669,10 +1669,13 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
{ {
unsigned int j; unsigned int j;
int ret; int ret;
struct xt_mtchk_param mtpar;
j = 0; j = 0;
ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, mtpar.table = name;
e->comefrom, &j); mtpar.entryinfo = &e->ipv6;
mtpar.hook_mask = e->comefrom;
ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j);
if (ret) if (ret)
goto cleanup_matches; goto cleanup_matches;
...@@ -2166,14 +2169,9 @@ icmp6_match(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -2166,14 +2169,9 @@ icmp6_match(const struct sk_buff *skb, const struct xt_match_param *par)
} }
/* Called when user tries to insert an entry of this type. */ /* Called when user tries to insert an entry of this type. */
static bool static bool icmp6_checkentry(const struct xt_mtchk_param *par)
icmp6_checkentry(const char *tablename,
const void *entry,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask)
{ {
const struct ip6t_icmp *icmpinfo = matchinfo; const struct ip6t_icmp *icmpinfo = par->matchinfo;
/* Must specify no unknown invflags */ /* Must specify no unknown invflags */
return !(icmpinfo->invflags & ~IP6T_ICMP_INV); return !(icmpinfo->invflags & ~IP6T_ICMP_INV);
......
...@@ -90,13 +90,9 @@ static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -90,13 +90,9 @@ static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
!(ahinfo->hdrres && ah->reserved); !(ahinfo->hdrres && ah->reserved);
} }
/* Called when user tries to insert an entry of this type. */ static bool ah_mt6_check(const struct xt_mtchk_param *par)
static bool
ah_mt6_check(const char *tablename, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ip6t_ah *ahinfo = matchinfo; const struct ip6t_ah *ahinfo = par->matchinfo;
if (ahinfo->invflags & ~IP6T_AH_INV_MASK) { if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags); pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
......
...@@ -107,13 +107,9 @@ frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -107,13 +107,9 @@ frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
&& (ntohs(fh->frag_off) & IP6_MF)); && (ntohs(fh->frag_off) & IP6_MF));
} }
/* Called when user tries to insert an entry of this type. */ static bool frag_mt6_check(const struct xt_mtchk_param *par)
static bool
frag_mt6_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ip6t_frag *fraginfo = matchinfo; const struct ip6t_frag *fraginfo = par->matchinfo;
if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags); pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
......
...@@ -160,13 +160,9 @@ hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -160,13 +160,9 @@ hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
return false; return false;
} }
/* Called when user tries to insert an entry of this type. */ static bool hbh_mt6_check(const struct xt_mtchk_param *par)
static bool
hbh_mt6_check(const char *tablename, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ip6t_opts *optsinfo = matchinfo; const struct ip6t_opts *optsinfo = par->matchinfo;
if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) { if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
......
...@@ -118,12 +118,9 @@ ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -118,12 +118,9 @@ ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
} }
} }
static bool static bool ipv6header_mt6_check(const struct xt_mtchk_param *par)
ipv6header_mt6_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ip6t_ipv6header_info *info = matchinfo; const struct ip6t_ipv6header_info *info = par->matchinfo;
/* invflags is 0 or 0xff in hard mode */ /* invflags is 0 or 0xff in hard mode */
if ((!info->modeflag) && info->invflags != 0x00 && if ((!info->modeflag) && info->invflags != 0x00 &&
......
...@@ -67,13 +67,9 @@ static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -67,13 +67,9 @@ static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
!!(mhinfo->invflags & IP6T_MH_INV_TYPE)); !!(mhinfo->invflags & IP6T_MH_INV_TYPE));
} }
/* Called when user tries to insert an entry of this type. */ static bool mh_mt6_check(const struct xt_mtchk_param *par)
static bool
mh_mt6_check(const char *tablename, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ip6t_mh *mhinfo = matchinfo; const struct ip6t_mh *mhinfo = par->matchinfo;
/* Must specify no unknown invflags */ /* Must specify no unknown invflags */
return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
......
...@@ -186,13 +186,9 @@ static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -186,13 +186,9 @@ static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
return false; return false;
} }
/* Called when user tries to insert an entry of this type. */ static bool rt_mt6_check(const struct xt_mtchk_param *par)
static bool
rt_mt6_check(const char *tablename, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ip6t_rt *rtinfo = matchinfo; const struct ip6t_rt *rtinfo = par->matchinfo;
if (rtinfo->invflags & ~IP6T_RT_INV_MASK) { if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags); pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
......
...@@ -321,39 +321,39 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target, ...@@ -321,39 +321,39 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target,
} }
EXPORT_SYMBOL_GPL(xt_find_revision); EXPORT_SYMBOL_GPL(xt_find_revision);
int xt_check_match(const struct xt_match *match, unsigned short family, int xt_check_match(struct xt_mtchk_param *par, u_int8_t family,
unsigned int size, const char *table, unsigned int hook_mask, unsigned int size, u_int8_t proto, bool inv_proto)
unsigned short proto, int inv_proto, const void *entry,
void *matchinfo)
{ {
if (XT_ALIGN(match->matchsize) != size && if (XT_ALIGN(par->match->matchsize) != size &&
match->matchsize != -1) { par->match->matchsize != -1) {
/* /*
* ebt_among is exempt from centralized matchsize checking * ebt_among is exempt from centralized matchsize checking
* because it uses a dynamic-size data set. * because it uses a dynamic-size data set.
*/ */
printk("%s_tables: %s match: invalid size %Zu != %u\n", printk("%s_tables: %s match: invalid size %Zu != %u\n",
xt_prefix[family], match->name, xt_prefix[family], par->match->name,
XT_ALIGN(match->matchsize), size); XT_ALIGN(par->match->matchsize), size);
return -EINVAL; return -EINVAL;
} }
if (match->table && strcmp(match->table, table)) { if (par->match->table != NULL &&
strcmp(par->match->table, par->table) != 0) {
printk("%s_tables: %s match: only valid in %s table, not %s\n", printk("%s_tables: %s match: only valid in %s table, not %s\n",
xt_prefix[family], match->name, match->table, table); xt_prefix[family], par->match->name,
par->match->table, par->table);
return -EINVAL; return -EINVAL;
} }
if (match->hooks && (hook_mask & ~match->hooks) != 0) { if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) {
printk("%s_tables: %s match: bad hook_mask %#x/%#x\n", printk("%s_tables: %s match: bad hook_mask %#x/%#x\n",
xt_prefix[family], match->name, hook_mask, match->hooks); xt_prefix[family], par->match->name,
par->hook_mask, par->match->hooks);
return -EINVAL; return -EINVAL;
} }
if (match->proto && (match->proto != proto || inv_proto)) { if (par->match->proto && (par->match->proto != proto || inv_proto)) {
printk("%s_tables: %s match: only valid for protocol %u\n", printk("%s_tables: %s match: only valid for protocol %u\n",
xt_prefix[family], match->name, match->proto); xt_prefix[family], par->match->name, par->match->proto);
return -EINVAL; return -EINVAL;
} }
if (match->checkentry != NULL && if (par->match->checkentry != NULL && !par->match->checkentry(par))
!match->checkentry(table, entry, match, matchinfo, hook_mask))
return -EINVAL; return -EINVAL;
return 0; return 0;
} }
......
...@@ -92,12 +92,9 @@ connbytes_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -92,12 +92,9 @@ connbytes_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return what >= sinfo->count.from; return what >= sinfo->count.from;
} }
static bool static bool connbytes_mt_check(const struct xt_mtchk_param *par)
connbytes_mt_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_connbytes_info *sinfo = matchinfo; const struct xt_connbytes_info *sinfo = par->matchinfo;
if (sinfo->what != XT_CONNBYTES_PKTS && if (sinfo->what != XT_CONNBYTES_PKTS &&
sinfo->what != XT_CONNBYTES_BYTES && sinfo->what != XT_CONNBYTES_BYTES &&
...@@ -109,17 +106,16 @@ connbytes_mt_check(const char *tablename, const void *ip, ...@@ -109,17 +106,16 @@ connbytes_mt_check(const char *tablename, const void *ip,
sinfo->direction != XT_CONNBYTES_DIR_BOTH) sinfo->direction != XT_CONNBYTES_DIR_BOTH)
return false; return false;
if (nf_ct_l3proto_try_module_get(match->family) < 0) { if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
printk(KERN_WARNING "can't load conntrack support for " printk(KERN_WARNING "can't load conntrack support for "
"proto=%u\n", match->family); "proto=%u\n", par->match->family);
return false; return false;
} }
return true; return true;
} }
static void static void connbytes_mt_destroy(const struct xt_match *match, void *matchinfo)
connbytes_mt_destroy(const struct xt_match *match, void *matchinfo)
{ {
nf_ct_l3proto_module_put(match->family); nf_ct_l3proto_module_put(match->family);
} }
......
...@@ -221,24 +221,21 @@ connlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -221,24 +221,21 @@ connlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return false; return false;
} }
static bool static bool connlimit_mt_check(const struct xt_mtchk_param *par)
connlimit_mt_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
struct xt_connlimit_info *info = matchinfo; struct xt_connlimit_info *info = par->matchinfo;
unsigned int i; unsigned int i;
if (nf_ct_l3proto_try_module_get(match->family) < 0) { if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
printk(KERN_WARNING "cannot load conntrack support for " printk(KERN_WARNING "cannot load conntrack support for "
"address family %u\n", match->family); "address family %u\n", par->match->family);
return false; return false;
} }
/* init private data */ /* init private data */
info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL); info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL);
if (info->data == NULL) { if (info->data == NULL) {
nf_ct_l3proto_module_put(match->family); nf_ct_l3proto_module_put(par->match->family);
return false; return false;
} }
......
...@@ -61,33 +61,27 @@ connmark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -61,33 +61,27 @@ connmark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
return ((ct->mark & info->mask) == info->mark) ^ info->invert; return ((ct->mark & info->mask) == info->mark) ^ info->invert;
} }
static bool static bool connmark_mt_check_v0(const struct xt_mtchk_param *par)
connmark_mt_check_v0(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_connmark_info *cm = matchinfo; const struct xt_connmark_info *cm = par->matchinfo;
if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) {
printk(KERN_WARNING "connmark: only support 32bit mark\n"); printk(KERN_WARNING "connmark: only support 32bit mark\n");
return false; return false;
} }
if (nf_ct_l3proto_try_module_get(match->family) < 0) { if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
printk(KERN_WARNING "can't load conntrack support for " printk(KERN_WARNING "can't load conntrack support for "
"proto=%u\n", match->family); "proto=%u\n", par->match->family);
return false; return false;
} }
return true; return true;
} }
static bool static bool connmark_mt_check(const struct xt_mtchk_param *par)
connmark_mt_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
if (nf_ct_l3proto_try_module_get(match->family) < 0) { if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
printk(KERN_WARNING "cannot load conntrack support for " printk(KERN_WARNING "cannot load conntrack support for "
"proto=%u\n", match->family); "proto=%u\n", par->match->family);
return false; return false;
} }
return true; return true;
......
...@@ -278,14 +278,11 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -278,14 +278,11 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool static bool conntrack_mt_check(const struct xt_mtchk_param *par)
conntrack_mt_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
if (nf_ct_l3proto_try_module_get(match->family) < 0) { if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
printk(KERN_WARNING "can't load conntrack support for " printk(KERN_WARNING "can't load conntrack support for "
"proto=%u\n", match->family); "proto=%u\n", par->match->family);
return false; return false;
} }
return true; return true;
......
...@@ -121,12 +121,9 @@ dccp_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -121,12 +121,9 @@ dccp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
XT_DCCP_OPTION, info->flags, info->invflags); XT_DCCP_OPTION, info->flags, info->invflags);
} }
static bool static bool dccp_mt_check(const struct xt_mtchk_param *par)
dccp_mt_check(const char *tablename, const void *inf,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_dccp_info *info = matchinfo; const struct xt_dccp_info *info = par->matchinfo;
return !(info->flags & ~XT_DCCP_VALID_FLAGS) return !(info->flags & ~XT_DCCP_VALID_FLAGS)
&& !(info->invflags & ~XT_DCCP_VALID_FLAGS) && !(info->invflags & ~XT_DCCP_VALID_FLAGS)
......
...@@ -43,15 +43,12 @@ dscp_mt6(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -43,15 +43,12 @@ dscp_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
return (dscp == info->dscp) ^ !!info->invert; return (dscp == info->dscp) ^ !!info->invert;
} }
static bool static bool dscp_mt_check(const struct xt_mtchk_param *par)
dscp_mt_check(const char *tablename, const void *info,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp; const struct xt_dscp_info *info = par->matchinfo;
if (dscp > XT_DSCP_MAX) { if (info->dscp > XT_DSCP_MAX) {
printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp); printk(KERN_ERR "xt_dscp: dscp %x out of range\n", info->dscp);
return false; return false;
} }
......
...@@ -66,13 +66,9 @@ static bool esp_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -66,13 +66,9 @@ static bool esp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
!!(espinfo->invflags & XT_ESP_INV_SPI)); !!(espinfo->invflags & XT_ESP_INV_SPI));
} }
/* Called when user tries to insert an entry of this type. */ static bool esp_mt_check(const struct xt_mtchk_param *par)
static bool
esp_mt_check(const char *tablename, const void *ip_void,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_esp *espinfo = matchinfo; const struct xt_esp *espinfo = par->matchinfo;
if (espinfo->invflags & ~XT_ESP_INV_MASK) { if (espinfo->invflags & ~XT_ESP_INV_MASK) {
duprintf("xt_esp: unknown flags %X\n", espinfo->invflags); duprintf("xt_esp: unknown flags %X\n", espinfo->invflags);
......
...@@ -664,12 +664,9 @@ hashlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -664,12 +664,9 @@ hashlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return false; return false;
} }
static bool static bool hashlimit_mt_check_v0(const struct xt_mtchk_param *par)
hashlimit_mt_check_v0(const char *tablename, const void *inf,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
struct xt_hashlimit_info *r = matchinfo; struct xt_hashlimit_info *r = par->matchinfo;
/* Check for overflow. */ /* Check for overflow. */
if (r->cfg.burst == 0 || if (r->cfg.burst == 0 ||
...@@ -698,8 +695,8 @@ hashlimit_mt_check_v0(const char *tablename, const void *inf, ...@@ -698,8 +695,8 @@ hashlimit_mt_check_v0(const char *tablename, const void *inf,
* the list of htable's in htable_create(), since then we would * the list of htable's in htable_create(), since then we would
* create duplicate proc files. -HW */ * create duplicate proc files. -HW */
mutex_lock(&hlimit_mutex); mutex_lock(&hlimit_mutex);
r->hinfo = htable_find_get(r->name, match->family); r->hinfo = htable_find_get(r->name, par->match->family);
if (!r->hinfo && htable_create_v0(r, match->family) != 0) { if (!r->hinfo && htable_create_v0(r, par->match->family) != 0) {
mutex_unlock(&hlimit_mutex); mutex_unlock(&hlimit_mutex);
return false; return false;
} }
...@@ -710,12 +707,9 @@ hashlimit_mt_check_v0(const char *tablename, const void *inf, ...@@ -710,12 +707,9 @@ hashlimit_mt_check_v0(const char *tablename, const void *inf,
return true; return true;
} }
static bool static bool hashlimit_mt_check(const struct xt_mtchk_param *par)
hashlimit_mt_check(const char *tablename, const void *inf,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
struct xt_hashlimit_mtinfo1 *info = matchinfo; struct xt_hashlimit_mtinfo1 *info = par->matchinfo;
/* Check for overflow. */ /* Check for overflow. */
if (info->cfg.burst == 0 || if (info->cfg.burst == 0 ||
...@@ -729,7 +723,7 @@ hashlimit_mt_check(const char *tablename, const void *inf, ...@@ -729,7 +723,7 @@ hashlimit_mt_check(const char *tablename, const void *inf,
return false; return false;
if (info->name[sizeof(info->name)-1] != '\0') if (info->name[sizeof(info->name)-1] != '\0')
return false; return false;
if (match->family == NFPROTO_IPV4) { if (par->match->family == NFPROTO_IPV4) {
if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32) if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32)
return false; return false;
} else { } else {
...@@ -744,8 +738,8 @@ hashlimit_mt_check(const char *tablename, const void *inf, ...@@ -744,8 +738,8 @@ hashlimit_mt_check(const char *tablename, const void *inf,
* the list of htable's in htable_create(), since then we would * the list of htable's in htable_create(), since then we would
* create duplicate proc files. -HW */ * create duplicate proc files. -HW */
mutex_lock(&hlimit_mutex); mutex_lock(&hlimit_mutex);
info->hinfo = htable_find_get(info->name, match->family); info->hinfo = htable_find_get(info->name, par->match->family);
if (!info->hinfo && htable_create(info, match->family) != 0) { if (!info->hinfo && htable_create(info, par->match->family) != 0) {
mutex_unlock(&hlimit_mutex); mutex_unlock(&hlimit_mutex);
return false; return false;
} }
......
...@@ -54,16 +54,13 @@ helper_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -54,16 +54,13 @@ helper_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return ret; return ret;
} }
static bool static bool helper_mt_check(const struct xt_mtchk_param *par)
helper_mt_check(const char *tablename, const void *inf,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
struct xt_helper_info *info = matchinfo; struct xt_helper_info *info = par->matchinfo;
if (nf_ct_l3proto_try_module_get(match->family) < 0) { if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
printk(KERN_WARNING "can't load conntrack support for " printk(KERN_WARNING "can't load conntrack support for "
"proto=%u\n", match->family); "proto=%u\n", par->match->family);
return false; return false;
} }
info->name[29] = '\0'; info->name[29] = '\0';
......
...@@ -92,12 +92,9 @@ user2credits(u_int32_t user) ...@@ -92,12 +92,9 @@ user2credits(u_int32_t user)
return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE; return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE;
} }
static bool static bool limit_mt_check(const struct xt_mtchk_param *par)
limit_mt_check(const char *tablename, const void *inf,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
struct xt_rateinfo *r = matchinfo; struct xt_rateinfo *r = par->matchinfo;
/* Check for overflow. */ /* Check for overflow. */
if (r->burst == 0 if (r->burst == 0
......
...@@ -38,12 +38,9 @@ mark_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -38,12 +38,9 @@ mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return ((skb->mark & info->mask) == info->mark) ^ info->invert; return ((skb->mark & info->mask) == info->mark) ^ info->invert;
} }
static bool static bool mark_mt_check_v0(const struct xt_mtchk_param *par)
mark_mt_check_v0(const char *tablename, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_mark_info *minfo = matchinfo; const struct xt_mark_info *minfo = par->matchinfo;
if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) {
printk(KERN_WARNING "mark: only supports 32bit mark\n"); printk(KERN_WARNING "mark: only supports 32bit mark\n");
......
...@@ -158,50 +158,37 @@ check(u_int16_t proto, ...@@ -158,50 +158,37 @@ check(u_int16_t proto,
&& count <= XT_MULTI_PORTS; && count <= XT_MULTI_PORTS;
} }
/* Called when user tries to insert an entry of this type. */ static bool multiport_mt_check_v0(const struct xt_mtchk_param *par)
static bool
multiport_mt_check_v0(const char *tablename, const void *info,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ipt_ip *ip = info; const struct ipt_ip *ip = par->entryinfo;
const struct xt_multiport *multiinfo = matchinfo; const struct xt_multiport *multiinfo = par->matchinfo;
return check(ip->proto, ip->invflags, multiinfo->flags, return check(ip->proto, ip->invflags, multiinfo->flags,
multiinfo->count); multiinfo->count);
} }
static bool static bool multiport_mt_check(const struct xt_mtchk_param *par)
multiport_mt_check(const char *tablename, const void *info,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ipt_ip *ip = info; const struct ipt_ip *ip = par->entryinfo;
const struct xt_multiport_v1 *multiinfo = matchinfo; const struct xt_multiport_v1 *multiinfo = par->matchinfo;
return check(ip->proto, ip->invflags, multiinfo->flags, return check(ip->proto, ip->invflags, multiinfo->flags,
multiinfo->count); multiinfo->count);
} }
static bool static bool multiport_mt6_check_v0(const struct xt_mtchk_param *par)
multiport_mt6_check_v0(const char *tablename, const void *info,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ip6t_ip6 *ip = info; const struct ip6t_ip6 *ip = par->entryinfo;
const struct xt_multiport *multiinfo = matchinfo; const struct xt_multiport *multiinfo = par->matchinfo;
return check(ip->proto, ip->invflags, multiinfo->flags, return check(ip->proto, ip->invflags, multiinfo->flags,
multiinfo->count); multiinfo->count);
} }
static bool static bool multiport_mt6_check(const struct xt_mtchk_param *par)
multiport_mt6_check(const char *tablename, const void *info,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ip6t_ip6 *ip = info; const struct ip6t_ip6 *ip = par->entryinfo;
const struct xt_multiport_v1 *multiinfo = matchinfo; const struct xt_multiport_v1 *multiinfo = par->matchinfo;
return check(ip->proto, ip->invflags, multiinfo->flags, return check(ip->proto, ip->invflags, multiinfo->flags,
multiinfo->count); multiinfo->count);
......
...@@ -107,12 +107,9 @@ owner_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -107,12 +107,9 @@ owner_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool static bool owner_mt_check_v0(const struct xt_mtchk_param *par)
owner_mt_check_v0(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ipt_owner_info *info = matchinfo; const struct ipt_owner_info *info = par->matchinfo;
if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) { if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) {
printk(KERN_WARNING KBUILD_MODNAME printk(KERN_WARNING KBUILD_MODNAME
...@@ -124,12 +121,9 @@ owner_mt_check_v0(const char *tablename, const void *ip, ...@@ -124,12 +121,9 @@ owner_mt_check_v0(const char *tablename, const void *ip,
return true; return true;
} }
static bool static bool owner_mt6_check_v0(const struct xt_mtchk_param *par)
owner_mt6_check_v0(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct ip6t_owner_info *info = matchinfo; const struct ip6t_owner_info *info = par->matchinfo;
if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) { if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
printk(KERN_WARNING KBUILD_MODNAME printk(KERN_WARNING KBUILD_MODNAME
......
...@@ -91,12 +91,9 @@ physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -91,12 +91,9 @@ physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT); return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT);
} }
static bool static bool physdev_mt_check(const struct xt_mtchk_param *par)
physdev_mt_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_physdev_info *info = matchinfo; const struct xt_physdev_info *info = par->matchinfo;
if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
info->bitmask & ~XT_PHYSDEV_OP_MASK) info->bitmask & ~XT_PHYSDEV_OP_MASK)
...@@ -104,12 +101,12 @@ physdev_mt_check(const char *tablename, const void *ip, ...@@ -104,12 +101,12 @@ physdev_mt_check(const char *tablename, const void *ip,
if (info->bitmask & XT_PHYSDEV_OP_OUT && if (info->bitmask & XT_PHYSDEV_OP_OUT &&
(!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
info->invert & XT_PHYSDEV_OP_BRIDGED) && info->invert & XT_PHYSDEV_OP_BRIDGED) &&
hook_mask & ((1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) | par->hook_mask & ((1 << NF_INET_LOCAL_OUT) |
(1 << NF_INET_POST_ROUTING))) { (1 << NF_INET_FORWARD) | (1 << NF_INET_POST_ROUTING))) {
printk(KERN_WARNING "physdev match: using --physdev-out in the " printk(KERN_WARNING "physdev match: using --physdev-out in the "
"OUTPUT, FORWARD and POSTROUTING chains for non-bridged " "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
"traffic is not supported anymore.\n"); "traffic is not supported anymore.\n");
if (hook_mask & (1 << NF_INET_LOCAL_OUT)) if (par->hook_mask & (1 << NF_INET_LOCAL_OUT))
return false; return false;
} }
return true; return true;
......
...@@ -128,26 +128,23 @@ policy_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -128,26 +128,23 @@ policy_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return ret; return ret;
} }
static bool static bool policy_mt_check(const struct xt_mtchk_param *par)
policy_mt_check(const char *tablename, const void *ip_void,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_policy_info *info = matchinfo; const struct xt_policy_info *info = par->matchinfo;
if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) { if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) {
printk(KERN_ERR "xt_policy: neither incoming nor " printk(KERN_ERR "xt_policy: neither incoming nor "
"outgoing policy selected\n"); "outgoing policy selected\n");
return false; return false;
} }
if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
&& info->flags & XT_POLICY_MATCH_OUT) { (1 << NF_INET_LOCAL_IN)) && info->flags & XT_POLICY_MATCH_OUT) {
printk(KERN_ERR "xt_policy: output policy not valid in " printk(KERN_ERR "xt_policy: output policy not valid in "
"PRE_ROUTING and INPUT\n"); "PRE_ROUTING and INPUT\n");
return false; return false;
} }
if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
&& info->flags & XT_POLICY_MATCH_IN) { (1 << NF_INET_LOCAL_OUT)) && info->flags & XT_POLICY_MATCH_IN) {
printk(KERN_ERR "xt_policy: input policy not valid in " printk(KERN_ERR "xt_policy: input policy not valid in "
"POST_ROUTING and OUTPUT\n"); "POST_ROUTING and OUTPUT\n");
return false; return false;
......
...@@ -37,12 +37,9 @@ quota_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -37,12 +37,9 @@ quota_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return ret; return ret;
} }
static bool static bool quota_mt_check(const struct xt_mtchk_param *par)
quota_mt_check(const char *tablename, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
struct xt_quota_info *q = matchinfo; struct xt_quota_info *q = par->matchinfo;
if (q->flags & ~XT_QUOTA_MASK) if (q->flags & ~XT_QUOTA_MASK)
return false; return false;
......
...@@ -74,13 +74,9 @@ xt_rateest_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -74,13 +74,9 @@ xt_rateest_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return ret; return ret;
} }
static bool xt_rateest_mt_checkentry(const char *tablename, static bool xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)
const void *ip,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask)
{ {
struct xt_rateest_match_info *info = matchinfo; struct xt_rateest_match_info *info = par->matchinfo;
struct xt_rateest *est1, *est2; struct xt_rateest *est1, *est2;
if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS | if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS |
......
...@@ -280,12 +280,9 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -280,12 +280,9 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return ret; return ret;
} }
static bool static bool recent_mt_check(const struct xt_mtchk_param *par)
recent_mt_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_recent_mtinfo *info = matchinfo; const struct xt_recent_mtinfo *info = par->matchinfo;
struct recent_table *t; struct recent_table *t;
unsigned i; unsigned i;
bool ret = false; bool ret = false;
......
...@@ -147,12 +147,9 @@ sctp_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -147,12 +147,9 @@ sctp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
} }
static bool static bool sctp_mt_check(const struct xt_mtchk_param *par)
sctp_mt_check(const char *tablename, const void *inf,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_sctp_info *info = matchinfo; const struct xt_sctp_info *info = par->matchinfo;
return !(info->flags & ~XT_SCTP_VALID_FLAGS) return !(info->flags & ~XT_SCTP_VALID_FLAGS)
&& !(info->invflags & ~XT_SCTP_VALID_FLAGS) && !(info->invflags & ~XT_SCTP_VALID_FLAGS)
......
...@@ -37,14 +37,11 @@ state_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -37,14 +37,11 @@ state_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return (sinfo->statemask & statebit); return (sinfo->statemask & statebit);
} }
static bool static bool state_mt_check(const struct xt_mtchk_param *par)
state_mt_check(const char *tablename, const void *inf,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
if (nf_ct_l3proto_try_module_get(match->family) < 0) { if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
printk(KERN_WARNING "can't load conntrack support for " printk(KERN_WARNING "can't load conntrack support for "
"proto=%u\n", match->family); "proto=%u\n", par->match->family);
return false; return false;
} }
return true; return true;
......
...@@ -49,12 +49,9 @@ statistic_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -49,12 +49,9 @@ statistic_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return ret; return ret;
} }
static bool static bool statistic_mt_check(const struct xt_mtchk_param *par)
statistic_mt_check(const char *tablename, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
struct xt_statistic_info *info = matchinfo; struct xt_statistic_info *info = par->matchinfo;
if (info->mode > XT_STATISTIC_MODE_MAX || if (info->mode > XT_STATISTIC_MODE_MAX ||
info->flags & ~XT_STATISTIC_MASK) info->flags & ~XT_STATISTIC_MASK)
......
...@@ -40,12 +40,9 @@ string_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -40,12 +40,9 @@ string_mt(const struct sk_buff *skb, const struct xt_match_param *par)
#define STRING_TEXT_PRIV(m) ((struct xt_string_info *)(m)) #define STRING_TEXT_PRIV(m) ((struct xt_string_info *)(m))
static bool static bool string_mt_check(const struct xt_mtchk_param *par)
string_mt_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
struct xt_string_info *conf = matchinfo; struct xt_string_info *conf = par->matchinfo;
struct ts_config *ts_conf; struct ts_config *ts_conf;
int flags = TS_AUTOLOAD; int flags = TS_AUTOLOAD;
...@@ -56,7 +53,7 @@ string_mt_check(const char *tablename, const void *ip, ...@@ -56,7 +53,7 @@ string_mt_check(const char *tablename, const void *ip,
return false; return false;
if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE) if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE)
return false; return false;
if (match->revision == 1) { if (par->match->revision == 1) {
if (conf->u.v1.flags & if (conf->u.v1.flags &
~(XT_STRING_FLAG_IGNORECASE | XT_STRING_FLAG_INVERT)) ~(XT_STRING_FLAG_IGNORECASE | XT_STRING_FLAG_INVERT))
return false; return false;
......
...@@ -126,13 +126,9 @@ static bool tcp_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -126,13 +126,9 @@ static bool tcp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
/* Called when user tries to insert an entry of this type. */ static bool tcp_mt_check(const struct xt_mtchk_param *par)
static bool
tcp_mt_check(const char *tablename, const void *info,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_tcp *tcpinfo = matchinfo; const struct xt_tcp *tcpinfo = par->matchinfo;
/* Must specify no unknown invflags */ /* Must specify no unknown invflags */
return !(tcpinfo->invflags & ~XT_TCP_INV_MASK); return !(tcpinfo->invflags & ~XT_TCP_INV_MASK);
...@@ -165,13 +161,9 @@ static bool udp_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -165,13 +161,9 @@ static bool udp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
!!(udpinfo->invflags & XT_UDP_INV_DSTPT)); !!(udpinfo->invflags & XT_UDP_INV_DSTPT));
} }
/* Called when user tries to insert an entry of this type. */ static bool udp_mt_check(const struct xt_mtchk_param *par)
static bool
udp_mt_check(const char *tablename, const void *info,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_udp *udpinfo = matchinfo; const struct xt_udp *udpinfo = par->matchinfo;
/* Must specify no unknown invflags */ /* Must specify no unknown invflags */
return !(udpinfo->invflags & ~XT_UDP_INV_MASK); return !(udpinfo->invflags & ~XT_UDP_INV_MASK);
......
...@@ -218,12 +218,9 @@ time_mt(const struct sk_buff *skb, const struct xt_match_param *par) ...@@ -218,12 +218,9 @@ time_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool static bool time_mt_check(const struct xt_mtchk_param *par)
time_mt_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
{ {
const struct xt_time_info *info = matchinfo; const struct xt_time_info *info = par->matchinfo;
if (info->daytime_start > XT_TIME_MAX_DAYTIME || if (info->daytime_start > XT_TIME_MAX_DAYTIME ||
info->daytime_stop > XT_TIME_MAX_DAYTIME) { info->daytime_stop > XT_TIME_MAX_DAYTIME) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment