* @fragoff: packet is a fragment, this is the data offset
* @thoff: position of transport header relative to skb->data
* @hotdrop: drop packet if we had inspection problems
+ * @family: Actual NFPROTO_* through which the function is invoked
+ * (helpful when match->family == NFPROTO_UNSPEC)
*/
struct xt_match_param {
const struct net_device *in, *out;
int fragoff;
unsigned int thoff;
bool *hotdrop;
+ u_int8_t family;
};
/**
const struct xt_match *match;
void *matchinfo;
unsigned int hook_mask;
+ u_int8_t family;
};
/* Match destructor parameters */
struct xt_mtdtor_param {
const struct xt_match *match;
void *matchinfo;
+ u_int8_t family;
};
/**
unsigned int hooknum;
const struct xt_target *target;
const void *targinfo;
+ u_int8_t family;
};
/**
const struct xt_target *target;
void *targinfo;
unsigned int hook_mask;
+ u_int8_t family;
};
/* Target destructor parameters */
struct xt_tgdtor_param {
const struct xt_target *target;
void *targinfo;
+ u_int8_t family;
};
struct xt_match
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(struct xt_mtchk_param *, u_int8_t family,
+extern int xt_check_match(struct xt_mtchk_param *,
unsigned int size, u_int8_t proto, bool inv_proto);
-extern int xt_check_target(struct xt_tgchk_param *, u_int8_t family,
+extern int xt_check_target(struct xt_tgchk_param *,
unsigned int size, u_int8_t proto, bool inv_proto);
extern struct xt_table *xt_register_table(struct net *net,
struct xt_match_param mtpar;
struct xt_target_param tgpar;
+ mtpar.family = tgpar.family = NFPROTO_BRIDGE;
mtpar.in = tgpar.in = in;
mtpar.out = tgpar.out = out;
mtpar.hotdrop = &hotdrop;
par->match = match;
par->matchinfo = m->data;
- ret = xt_check_match(par, NFPROTO_BRIDGE, m->match_size,
+ ret = xt_check_match(par, m->match_size,
e->ethproto, e->invflags & EBT_IPROTO);
if (ret < 0) {
module_put(match->me);
par->target = watcher;
par->targinfo = w->data;
- ret = xt_check_target(par, NFPROTO_BRIDGE, w->watcher_size,
+ ret = xt_check_target(par, w->watcher_size,
e->ethproto, e->invflags & EBT_IPROTO);
if (ret < 0) {
module_put(watcher->me);
par.match = m->u.match;
par.matchinfo = m->data;
+ par.family = NFPROTO_BRIDGE;
if (par.match->destroy != NULL)
par.match->destroy(&par);
module_put(par.match->me);
par.target = w->u.watcher;
par.targinfo = w->data;
+ par.family = NFPROTO_BRIDGE;
if (par.target->destroy != NULL)
par.target->destroy(&par);
module_put(par.target->me);
par.target = t->u.target;
par.targinfo = t->data;
+ par.family = NFPROTO_BRIDGE;
if (par.target->destroy != NULL)
par.target->destroy(&par);
module_put(par.target->me);
mtpar.table = tgpar.table = name;
mtpar.entryinfo = tgpar.entryinfo = e;
mtpar.hook_mask = tgpar.hook_mask = hookmask;
+ mtpar.family = tgpar.family = NFPROTO_BRIDGE;
ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i);
if (ret != 0)
goto cleanup_matches;
tgpar.target = target;
tgpar.targinfo = t->data;
- ret = xt_check_target(&tgpar, NFPROTO_BRIDGE, t->target_size,
+ ret = xt_check_target(&tgpar, t->target_size,
e->ethproto, e->invflags & EBT_IPROTO);
if (ret < 0) {
module_put(target->me);
tgpar.in = in;
tgpar.out = out;
tgpar.hooknum = hook;
+ tgpar.family = NFPROTO_ARP;
arp = arp_hdr(skb);
do {
.target = t->u.kernel.target,
.targinfo = t->data,
.hook_mask = e->comefrom,
+ .family = NFPROTO_ARP,
};
- ret = xt_check_target(&par, NFPROTO_ARP,
- t->u.target_size - sizeof(*t), 0, false);
+ ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
if (ret < 0) {
duprintf("arp_tables: check failed for `%s'.\n",
t->u.kernel.target->name);
t = arpt_get_target(e);
par.target = t->u.kernel.target;
par.targinfo = t->data;
+ par.family = NFPROTO_ARP;
if (par.target->destroy != NULL)
par.target->destroy(&par);
module_put(par.target->me);
mtpar.hotdrop = &hotdrop;
mtpar.in = tgpar.in = in;
mtpar.out = tgpar.out = out;
+ mtpar.family = tgpar.family = NFPROTO_IPV4;
tgpar.hooknum = hook;
read_lock_bh(&table->lock);
par.match = m->u.kernel.match;
par.matchinfo = m->data;
+ par.family = NFPROTO_IPV4;
if (par.match->destroy != NULL)
par.match->destroy(&par);
module_put(par.match->me);
par->match = m->u.kernel.match;
par->matchinfo = m->data;
- ret = xt_check_match(par, NFPROTO_IPV4, m->u.match_size - sizeof(*m),
+ ret = xt_check_match(par, m->u.match_size - sizeof(*m),
ip->proto, ip->invflags & IPT_INV_PROTO);
if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n",
.target = t->u.kernel.target,
.targinfo = t->data,
.hook_mask = e->comefrom,
+ .family = NFPROTO_IPV4,
};
int ret;
- ret = xt_check_target(&par, NFPROTO_IPV4, t->u.target_size - sizeof(*t),
+ ret = xt_check_target(&par, 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",
mtpar.table = name;
mtpar.entryinfo = &e->ip;
mtpar.hook_mask = e->comefrom;
+ mtpar.family = NFPROTO_IPV4;
ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
if (ret != 0)
goto cleanup_matches;
par.target = t->u.kernel.target;
par.targinfo = t->data;
+ par.family = NFPROTO_IPV4;
if (par.target->destroy != NULL)
par.target->destroy(&par);
module_put(par.target->me);
mtpar.table = name;
mtpar.entryinfo = &e->ip;
mtpar.hook_mask = e->comefrom;
+ mtpar.family = NFPROTO_IPV4;
ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
if (ret)
goto cleanup_matches;
mtpar.hotdrop = &hotdrop;
mtpar.in = tgpar.in = in;
mtpar.out = tgpar.out = out;
+ mtpar.family = tgpar.family = NFPROTO_IPV6;
tgpar.hooknum = hook;
read_lock_bh(&table->lock);
par.match = m->u.kernel.match;
par.matchinfo = m->data;
+ par.family = NFPROTO_IPV6;
if (par.match->destroy != NULL)
par.match->destroy(&par);
module_put(par.match->me);
par->match = m->u.kernel.match;
par->matchinfo = m->data;
- ret = xt_check_match(par, NFPROTO_IPV6, m->u.match_size - sizeof(*m),
+ ret = xt_check_match(par, m->u.match_size - sizeof(*m),
ipv6->proto, ipv6->invflags & IP6T_INV_PROTO);
if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n",
.target = t->u.kernel.target,
.targinfo = t->data,
.hook_mask = e->comefrom,
+ .family = NFPROTO_IPV6,
};
int ret;
t = ip6t_get_target(e);
- ret = xt_check_target(&par, NFPROTO_IPV6, t->u.target_size - sizeof(*t),
+ ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO);
if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n",
mtpar.table = name;
mtpar.entryinfo = &e->ipv6;
mtpar.hook_mask = e->comefrom;
+ mtpar.family = NFPROTO_IPV6;
ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
if (ret != 0)
goto cleanup_matches;
par.target = t->u.kernel.target;
par.targinfo = t->data;
+ par.family = NFPROTO_IPV6;
if (par.target->destroy != NULL)
par.target->destroy(&par);
module_put(par.target->me);
mtpar.table = name;
mtpar.entryinfo = &e->ipv6;
mtpar.hook_mask = e->comefrom;
+ mtpar.family = NFPROTO_IPV6;
ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j);
if (ret)
goto cleanup_matches;
}
EXPORT_SYMBOL_GPL(xt_find_revision);
-int xt_check_match(struct xt_mtchk_param *par, u_int8_t family,
+int xt_check_match(struct xt_mtchk_param *par,
unsigned int size, u_int8_t proto, bool inv_proto)
{
if (XT_ALIGN(par->match->matchsize) != size &&
* because it uses a dynamic-size data set.
*/
printk("%s_tables: %s match: invalid size %Zu != %u\n",
- xt_prefix[family], par->match->name,
+ xt_prefix[par->family], par->match->name,
XT_ALIGN(par->match->matchsize), size);
return -EINVAL;
}
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",
- xt_prefix[family], par->match->name,
+ xt_prefix[par->family], par->match->name,
par->match->table, par->table);
return -EINVAL;
}
if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) {
printk("%s_tables: %s match: bad hook_mask %#x/%#x\n",
- xt_prefix[family], par->match->name,
+ xt_prefix[par->family], par->match->name,
par->hook_mask, par->match->hooks);
return -EINVAL;
}
if (par->match->proto && (par->match->proto != proto || inv_proto)) {
printk("%s_tables: %s match: only valid for protocol %u\n",
- xt_prefix[family], par->match->name, par->match->proto);
+ xt_prefix[par->family], par->match->name,
+ par->match->proto);
return -EINVAL;
}
if (par->match->checkentry != NULL && !par->match->checkentry(par))
EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
#endif /* CONFIG_COMPAT */
-int xt_check_target(struct xt_tgchk_param *par, u_int8_t family,
+int xt_check_target(struct xt_tgchk_param *par,
unsigned int size, u_int8_t proto, bool inv_proto)
{
if (XT_ALIGN(par->target->targetsize) != size) {
printk("%s_tables: %s target: invalid size %Zu != %u\n",
- xt_prefix[family], par->target->name,
+ xt_prefix[par->family], par->target->name,
XT_ALIGN(par->target->targetsize), size);
return -EINVAL;
}
if (par->target->table != NULL &&
strcmp(par->target->table, par->table) != 0) {
printk("%s_tables: %s target: only valid in %s table, not %s\n",
- xt_prefix[family], par->target->name,
+ xt_prefix[par->family], par->target->name,
par->target->table, par->table);
return -EINVAL;
}
if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) {
printk("%s_tables: %s target: bad hook_mask %#x/%#x\n",
- xt_prefix[family], par->target->name, par->hook_mask,
- par->target->hooks);
+ xt_prefix[par->family], par->target->name,
+ par->hook_mask, par->target->hooks);
return -EINVAL;
}
if (par->target->proto && (par->target->proto != proto || inv_proto)) {
printk("%s_tables: %s target: only valid for protocol %u\n",
- xt_prefix[family], par->target->name,
+ xt_prefix[par->family], par->target->name,
par->target->proto);
return -EINVAL;
}
par.target = target;
par.targinfo = t->data;
par.hook_mask = hook;
+ par.family = NFPROTO_IPV4;
- ret = xt_check_target(&par, NFPROTO_IPV4,
- t->u.target_size - sizeof(*t), 0, false);
+ ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
if (ret < 0) {
module_put(t->u.kernel.target->me);
return ret;