Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 916a917d authored by Jan Engelhardt's avatar Jan Engelhardt Committed by Patrick McHardy
Browse files

netfilter: xtables: provide invoked family value to extensions



By passing in the family through which extensions were invoked, a bit
of data space can be reclaimed. The "family" member will be added to
the parameter structures and the check functions be adjusted.

Signed-off-by: default avatarJan Engelhardt <jengelh@medozas.de>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent a2df1648
Loading
Loading
Loading
Loading
+10 −2
Original line number Original line Diff line number Diff line
@@ -183,6 +183,8 @@ struct xt_counters_info
 * @fragoff:	packet is a fragment, this is the data offset
 * @fragoff:	packet is a fragment, this is the data offset
 * @thoff:	position of transport header relative to skb->data
 * @thoff:	position of transport header relative to skb->data
 * @hotdrop:	drop packet if we had inspection problems
 * @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 {
struct xt_match_param {
	const struct net_device *in, *out;
	const struct net_device *in, *out;
@@ -191,6 +193,7 @@ struct xt_match_param {
	int fragoff;
	int fragoff;
	unsigned int thoff;
	unsigned int thoff;
	bool *hotdrop;
	bool *hotdrop;
	u_int8_t family;
};
};


/**
/**
@@ -210,12 +213,14 @@ struct xt_mtchk_param {
	const struct xt_match *match;
	const struct xt_match *match;
	void *matchinfo;
	void *matchinfo;
	unsigned int hook_mask;
	unsigned int hook_mask;
	u_int8_t family;
};
};


/* Match destructor parameters */
/* Match destructor parameters */
struct xt_mtdtor_param {
struct xt_mtdtor_param {
	const struct xt_match *match;
	const struct xt_match *match;
	void *matchinfo;
	void *matchinfo;
	u_int8_t family;
};
};


/**
/**
@@ -232,6 +237,7 @@ struct xt_target_param {
	unsigned int hooknum;
	unsigned int hooknum;
	const struct xt_target *target;
	const struct xt_target *target;
	const void *targinfo;
	const void *targinfo;
	u_int8_t family;
};
};


/**
/**
@@ -249,12 +255,14 @@ struct xt_tgchk_param {
	const struct xt_target *target;
	const struct xt_target *target;
	void *targinfo;
	void *targinfo;
	unsigned int hook_mask;
	unsigned int hook_mask;
	u_int8_t family;
};
};


/* Target destructor parameters */
/* Target destructor parameters */
struct xt_tgdtor_param {
struct xt_tgdtor_param {
	const struct xt_target *target;
	const struct xt_target *target;
	void *targinfo;
	void *targinfo;
	u_int8_t family;
};
};


struct xt_match
struct xt_match
@@ -393,9 +401,9 @@ 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(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);
			  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);
			   unsigned int size, u_int8_t proto, bool inv_proto);


extern struct xt_table *xt_register_table(struct net *net,
extern struct xt_table *xt_register_table(struct net *net,
+8 −3
Original line number Original line Diff line number Diff line
@@ -160,6 +160,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
	struct xt_match_param mtpar;
	struct xt_match_param mtpar;
	struct xt_target_param tgpar;
	struct xt_target_param tgpar;


	mtpar.family  = tgpar.family = NFPROTO_BRIDGE;
	mtpar.in      = tgpar.in  = in;
	mtpar.in      = tgpar.in  = in;
	mtpar.out     = tgpar.out = out;
	mtpar.out     = tgpar.out = out;
	mtpar.hotdrop = &hotdrop;
	mtpar.hotdrop = &hotdrop;
@@ -351,7 +352,7 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,


	par->match     = match;
	par->match     = match;
	par->matchinfo = m->data;
	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);
	      e->ethproto, e->invflags & EBT_IPROTO);
	if (ret < 0) {
	if (ret < 0) {
		module_put(match->me);
		module_put(match->me);
@@ -386,7 +387,7 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,


	par->target   = watcher;
	par->target   = watcher;
	par->targinfo = w->data;
	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);
	      e->ethproto, e->invflags & EBT_IPROTO);
	if (ret < 0) {
	if (ret < 0) {
		module_put(watcher->me);
		module_put(watcher->me);
@@ -572,6 +573,7 @@ ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)


	par.match     = m->u.match;
	par.match     = m->u.match;
	par.matchinfo = m->data;
	par.matchinfo = m->data;
	par.family    = NFPROTO_BRIDGE;
	if (par.match->destroy != NULL)
	if (par.match->destroy != NULL)
		par.match->destroy(&par);
		par.match->destroy(&par);
	module_put(par.match->me);
	module_put(par.match->me);
@@ -588,6 +590,7 @@ ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)


	par.target   = w->u.watcher;
	par.target   = w->u.watcher;
	par.targinfo = w->data;
	par.targinfo = w->data;
	par.family   = NFPROTO_BRIDGE;
	if (par.target->destroy != NULL)
	if (par.target->destroy != NULL)
		par.target->destroy(&par);
		par.target->destroy(&par);
	module_put(par.target->me);
	module_put(par.target->me);
@@ -611,6 +614,7 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)


	par.target   = t->u.target;
	par.target   = t->u.target;
	par.targinfo = t->data;
	par.targinfo = t->data;
	par.family   = NFPROTO_BRIDGE;
	if (par.target->destroy != NULL)
	if (par.target->destroy != NULL)
		par.target->destroy(&par);
		par.target->destroy(&par);
	module_put(par.target->me);
	module_put(par.target->me);
@@ -673,6 +677,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
	mtpar.table     = tgpar.table     = name;
	mtpar.table     = tgpar.table     = name;
	mtpar.entryinfo = tgpar.entryinfo = e;
	mtpar.entryinfo = tgpar.entryinfo = e;
	mtpar.hook_mask = tgpar.hook_mask = hookmask;
	mtpar.hook_mask = tgpar.hook_mask = hookmask;
	mtpar.family    = tgpar.family    = NFPROTO_BRIDGE;
	ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i);
	ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i);
	if (ret != 0)
	if (ret != 0)
		goto cleanup_matches;
		goto cleanup_matches;
@@ -715,7 +720,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,


	tgpar.target   = target;
	tgpar.target   = target;
	tgpar.targinfo = t->data;
	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);
	      e->ethproto, e->invflags & EBT_IPROTO);
	if (ret < 0) {
	if (ret < 0) {
		module_put(target->me);
		module_put(target->me);
+4 −2
Original line number Original line Diff line number Diff line
@@ -246,6 +246,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
	tgpar.in      = in;
	tgpar.in      = in;
	tgpar.out     = out;
	tgpar.out     = out;
	tgpar.hooknum = hook;
	tgpar.hooknum = hook;
	tgpar.family  = NFPROTO_ARP;


	arp = arp_hdr(skb);
	arp = arp_hdr(skb);
	do {
	do {
@@ -465,10 +466,10 @@ static inline int check_target(struct arpt_entry *e, const char *name)
		.target    = t->u.kernel.target,
		.target    = t->u.kernel.target,
		.targinfo  = t->data,
		.targinfo  = t->data,
		.hook_mask = e->comefrom,
		.hook_mask = e->comefrom,
		.family    = NFPROTO_ARP,
	};
	};


	ret = xt_check_target(&par, NFPROTO_ARP,
	ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
	      t->u.target_size - sizeof(*t), 0, false);
	if (ret < 0) {
	if (ret < 0) {
		duprintf("arp_tables: check failed for `%s'.\n",
		duprintf("arp_tables: check failed for `%s'.\n",
			 t->u.kernel.target->name);
			 t->u.kernel.target->name);
@@ -566,6 +567,7 @@ static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
	t = arpt_get_target(e);
	t = arpt_get_target(e);
	par.target   = t->u.kernel.target;
	par.target   = t->u.kernel.target;
	par.targinfo = t->data;
	par.targinfo = t->data;
	par.family   = NFPROTO_ARP;
	if (par.target->destroy != NULL)
	if (par.target->destroy != NULL)
		par.target->destroy(&par);
		par.target->destroy(&par);
	module_put(par.target->me);
	module_put(par.target->me);
+8 −2
Original line number Original line Diff line number Diff line
@@ -348,6 +348,7 @@ ipt_do_table(struct sk_buff *skb,
	mtpar.hotdrop = &hotdrop;
	mtpar.hotdrop = &hotdrop;
	mtpar.in      = tgpar.in  = in;
	mtpar.in      = tgpar.in  = in;
	mtpar.out     = tgpar.out = out;
	mtpar.out     = tgpar.out = out;
	mtpar.family  = tgpar.family = NFPROTO_IPV4;
	tgpar.hooknum = hook;
	tgpar.hooknum = hook;


	read_lock_bh(&table->lock);
	read_lock_bh(&table->lock);
@@ -579,6 +580,7 @@ cleanup_match(struct ipt_entry_match *m, unsigned int *i)


	par.match     = m->u.kernel.match;
	par.match     = m->u.kernel.match;
	par.matchinfo = m->data;
	par.matchinfo = m->data;
	par.family    = NFPROTO_IPV4;
	if (par.match->destroy != NULL)
	if (par.match->destroy != NULL)
		par.match->destroy(&par);
		par.match->destroy(&par);
	module_put(par.match->me);
	module_put(par.match->me);
@@ -616,7 +618,7 @@ check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
	par->match     = m->u.kernel.match;
	par->match     = m->u.kernel.match;
	par->matchinfo = m->data;
	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);
	      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",
@@ -662,10 +664,11 @@ static int check_target(struct ipt_entry *e, const char *name)
		.target    = t->u.kernel.target,
		.target    = t->u.kernel.target,
		.targinfo  = t->data,
		.targinfo  = t->data,
		.hook_mask = e->comefrom,
		.hook_mask = e->comefrom,
		.family    = NFPROTO_IPV4,
	};
	};
	int ret;
	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);
	      e->ip.proto, e->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",
@@ -693,6 +696,7 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
	mtpar.table     = name;
	mtpar.table     = name;
	mtpar.entryinfo = &e->ip;
	mtpar.entryinfo = &e->ip;
	mtpar.hook_mask = e->comefrom;
	mtpar.hook_mask = e->comefrom;
	mtpar.family    = NFPROTO_IPV4;
	ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
	ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
	if (ret != 0)
	if (ret != 0)
		goto cleanup_matches;
		goto cleanup_matches;
@@ -780,6 +784,7 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i)


	par.target   = t->u.kernel.target;
	par.target   = t->u.kernel.target;
	par.targinfo = t->data;
	par.targinfo = t->data;
	par.family   = NFPROTO_IPV4;
	if (par.target->destroy != NULL)
	if (par.target->destroy != NULL)
		par.target->destroy(&par);
		par.target->destroy(&par);
	module_put(par.target->me);
	module_put(par.target->me);
@@ -1659,6 +1664,7 @@ compat_check_entry(struct ipt_entry *e, const char *name,
	mtpar.table     = name;
	mtpar.table     = name;
	mtpar.entryinfo = &e->ip;
	mtpar.entryinfo = &e->ip;
	mtpar.hook_mask = e->comefrom;
	mtpar.hook_mask = e->comefrom;
	mtpar.family    = NFPROTO_IPV4;
	ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
	ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
	if (ret)
	if (ret)
		goto cleanup_matches;
		goto cleanup_matches;
+8 −2
Original line number Original line Diff line number Diff line
@@ -370,6 +370,7 @@ ip6t_do_table(struct sk_buff *skb,
	mtpar.hotdrop = &hotdrop;
	mtpar.hotdrop = &hotdrop;
	mtpar.in      = tgpar.in  = in;
	mtpar.in      = tgpar.in  = in;
	mtpar.out     = tgpar.out = out;
	mtpar.out     = tgpar.out = out;
	mtpar.family  = tgpar.family = NFPROTO_IPV6;
	tgpar.hooknum = hook;
	tgpar.hooknum = hook;


	read_lock_bh(&table->lock);
	read_lock_bh(&table->lock);
@@ -604,6 +605,7 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i)


	par.match     = m->u.kernel.match;
	par.match     = m->u.kernel.match;
	par.matchinfo = m->data;
	par.matchinfo = m->data;
	par.family    = NFPROTO_IPV6;
	if (par.match->destroy != NULL)
	if (par.match->destroy != NULL)
		par.match->destroy(&par);
		par.match->destroy(&par);
	module_put(par.match->me);
	module_put(par.match->me);
@@ -640,7 +642,7 @@ static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
	par->match     = m->u.kernel.match;
	par->match     = m->u.kernel.match;
	par->matchinfo = m->data;
	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);
			     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",
@@ -686,11 +688,12 @@ static int check_target(struct ip6t_entry *e, const char *name)
		.target    = t->u.kernel.target,
		.target    = t->u.kernel.target,
		.targinfo  = t->data,
		.targinfo  = t->data,
		.hook_mask = e->comefrom,
		.hook_mask = e->comefrom,
		.family    = NFPROTO_IPV6,
	};
	};
	int ret;
	int ret;


	t = ip6t_get_target(e);
	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);
	      e->ipv6.proto, e->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",
@@ -718,6 +721,7 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
	mtpar.table     = name;
	mtpar.table     = name;
	mtpar.entryinfo = &e->ipv6;
	mtpar.entryinfo = &e->ipv6;
	mtpar.hook_mask = e->comefrom;
	mtpar.hook_mask = e->comefrom;
	mtpar.family    = NFPROTO_IPV6;
	ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
	ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
	if (ret != 0)
	if (ret != 0)
		goto cleanup_matches;
		goto cleanup_matches;
@@ -805,6 +809,7 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)


	par.target   = t->u.kernel.target;
	par.target   = t->u.kernel.target;
	par.targinfo = t->data;
	par.targinfo = t->data;
	par.family   = NFPROTO_IPV6;
	if (par.target->destroy != NULL)
	if (par.target->destroy != NULL)
		par.target->destroy(&par);
		par.target->destroy(&par);
	module_put(par.target->me);
	module_put(par.target->me);
@@ -1685,6 +1690,7 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
	mtpar.table     = name;
	mtpar.table     = name;
	mtpar.entryinfo = &e->ipv6;
	mtpar.entryinfo = &e->ipv6;
	mtpar.hook_mask = e->comefrom;
	mtpar.hook_mask = e->comefrom;
	mtpar.family    = NFPROTO_IPV6;
	ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j);
	ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j);
	if (ret)
	if (ret)
		goto cleanup_matches;
		goto cleanup_matches;
Loading