netfilter: xtables: combine struct xt_match_param and xt_target_param
The structures carried - besides match/target - almost the same data. It is possible to combine them, as extensions are evaluated serially, and so, the callers end up a little smaller. text data bss filename -15318 740 104 net/ipv4/netfilter/ip_tables.o +15286 740 104 net/ipv4/netfilter/ip_tables.o -15333 540 152 net/ipv6/netfilter/ip6_tables.o +15269 540 152 net/ipv6/netfilter/ip6_tables.o Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
This commit is contained in:
parent
ef53d702c3
commit
de74c16996
@ -182,13 +182,17 @@ struct xt_counters_info {
|
|||||||
|
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
|
#define xt_match_param xt_action_param
|
||||||
|
#define xt_target_param xt_action_param
|
||||||
/**
|
/**
|
||||||
* struct xt_match_param - parameters for match extensions' match functions
|
* struct xt_action_param - parameters for matches/targets
|
||||||
*
|
*
|
||||||
|
* @match: the match extension
|
||||||
|
* @target: the target extension
|
||||||
|
* @matchinfo: per-match data
|
||||||
|
* @targetinfo: per-target data
|
||||||
* @in: input netdevice
|
* @in: input netdevice
|
||||||
* @out: output netdevice
|
* @out: output netdevice
|
||||||
* @match: struct xt_match through which this function was invoked
|
|
||||||
* @matchinfo: per-match data
|
|
||||||
* @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
|
||||||
* @hook: hook number given packet came from
|
* @hook: hook number given packet came from
|
||||||
@ -197,10 +201,15 @@ struct xt_counters_info {
|
|||||||
* @hotdrop: drop packet if we had inspection problems
|
* @hotdrop: drop packet if we had inspection problems
|
||||||
* Network namespace obtainable using dev_net(in/out)
|
* Network namespace obtainable using dev_net(in/out)
|
||||||
*/
|
*/
|
||||||
struct xt_match_param {
|
struct xt_action_param {
|
||||||
|
union {
|
||||||
|
const struct xt_match *match;
|
||||||
|
const struct xt_target *target;
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
const void *matchinfo, *targinfo;
|
||||||
|
};
|
||||||
const struct net_device *in, *out;
|
const struct net_device *in, *out;
|
||||||
const struct xt_match *match;
|
|
||||||
const void *matchinfo;
|
|
||||||
int fragoff;
|
int fragoff;
|
||||||
unsigned int thoff;
|
unsigned int thoff;
|
||||||
unsigned int hooknum;
|
unsigned int hooknum;
|
||||||
@ -242,23 +251,6 @@ struct xt_mtdtor_param {
|
|||||||
u_int8_t family;
|
u_int8_t family;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct xt_target_param - parameters for target extensions' target functions
|
|
||||||
*
|
|
||||||
* @hooknum: hook through which this target was invoked
|
|
||||||
* @target: struct xt_target through which this function was invoked
|
|
||||||
* @targinfo: per-target data
|
|
||||||
*
|
|
||||||
* Other fields see above.
|
|
||||||
*/
|
|
||||||
struct xt_target_param {
|
|
||||||
const struct net_device *in, *out;
|
|
||||||
const struct xt_target *target;
|
|
||||||
const void *targinfo;
|
|
||||||
unsigned int hooknum;
|
|
||||||
u_int8_t family;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct xt_tgchk_param - parameters for target extensions'
|
* struct xt_tgchk_param - parameters for target extensions'
|
||||||
* checkentry functions
|
* checkentry functions
|
||||||
@ -298,7 +290,7 @@ struct xt_match {
|
|||||||
non-linear skb, using skb_header_pointer and
|
non-linear skb, using skb_header_pointer and
|
||||||
skb_ip_make_writable. */
|
skb_ip_make_writable. */
|
||||||
bool (*match)(const struct sk_buff *skb,
|
bool (*match)(const struct sk_buff *skb,
|
||||||
const struct xt_match_param *);
|
const struct xt_action_param *);
|
||||||
|
|
||||||
/* Called when user tries to insert an entry of this type. */
|
/* Called when user tries to insert an entry of this type. */
|
||||||
int (*checkentry)(const struct xt_mtchk_param *);
|
int (*checkentry)(const struct xt_mtchk_param *);
|
||||||
@ -335,7 +327,7 @@ struct xt_target {
|
|||||||
must now handle non-linear skbs, using skb_copy_bits and
|
must now handle non-linear skbs, using skb_copy_bits and
|
||||||
skb_ip_make_writable. */
|
skb_ip_make_writable. */
|
||||||
unsigned int (*target)(struct sk_buff *skb,
|
unsigned int (*target)(struct sk_buff *skb,
|
||||||
const struct xt_target_param *);
|
const struct xt_action_param *);
|
||||||
|
|
||||||
/* Called when user tries to insert an entry of this type:
|
/* Called when user tries to insert an entry of this type:
|
||||||
hook_mask is a bitmask of hooks from which it can be
|
hook_mask is a bitmask of hooks from which it can be
|
||||||
|
@ -86,7 +86,7 @@ static struct xt_target ebt_standard_target = {
|
|||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb,
|
ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb,
|
||||||
struct xt_target_param *par)
|
struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
par->target = w->u.watcher;
|
par->target = w->u.watcher;
|
||||||
par->targinfo = w->data;
|
par->targinfo = w->data;
|
||||||
@ -95,8 +95,9 @@ ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ebt_do_match (struct ebt_entry_match *m,
|
static inline int
|
||||||
const struct sk_buff *skb, struct xt_match_param *par)
|
ebt_do_match(struct ebt_entry_match *m, const struct sk_buff *skb,
|
||||||
|
struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
par->match = m->u.match;
|
par->match = m->u.match;
|
||||||
par->matchinfo = m->data;
|
par->matchinfo = m->data;
|
||||||
@ -186,14 +187,13 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
|
|||||||
const char *base;
|
const char *base;
|
||||||
const struct ebt_table_info *private;
|
const struct ebt_table_info *private;
|
||||||
bool hotdrop = false;
|
bool hotdrop = false;
|
||||||
struct xt_match_param mtpar;
|
struct xt_action_param acpar;
|
||||||
struct xt_target_param tgpar;
|
|
||||||
|
|
||||||
mtpar.family = tgpar.family = NFPROTO_BRIDGE;
|
acpar.family = NFPROTO_BRIDGE;
|
||||||
mtpar.in = tgpar.in = in;
|
acpar.in = in;
|
||||||
mtpar.out = tgpar.out = out;
|
acpar.out = out;
|
||||||
mtpar.hotdrop = &hotdrop;
|
acpar.hotdrop = &hotdrop;
|
||||||
mtpar.hooknum = tgpar.hooknum = hook;
|
acpar.hooknum = hook;
|
||||||
|
|
||||||
read_lock_bh(&table->lock);
|
read_lock_bh(&table->lock);
|
||||||
private = table->private;
|
private = table->private;
|
||||||
@ -214,7 +214,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
|
|||||||
if (ebt_basic_match(point, eth_hdr(skb), in, out))
|
if (ebt_basic_match(point, eth_hdr(skb), in, out))
|
||||||
goto letscontinue;
|
goto letscontinue;
|
||||||
|
|
||||||
if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &mtpar) != 0)
|
if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &acpar) != 0)
|
||||||
goto letscontinue;
|
goto letscontinue;
|
||||||
if (hotdrop) {
|
if (hotdrop) {
|
||||||
read_unlock_bh(&table->lock);
|
read_unlock_bh(&table->lock);
|
||||||
@ -227,7 +227,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
|
|||||||
|
|
||||||
/* these should only watch: not modify, nor tell us
|
/* these should only watch: not modify, nor tell us
|
||||||
what to do with the packet */
|
what to do with the packet */
|
||||||
EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, &tgpar);
|
EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, &acpar);
|
||||||
|
|
||||||
t = (struct ebt_entry_target *)
|
t = (struct ebt_entry_target *)
|
||||||
(((char *)point) + point->target_offset);
|
(((char *)point) + point->target_offset);
|
||||||
@ -235,9 +235,9 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
|
|||||||
if (!t->u.target->target)
|
if (!t->u.target->target)
|
||||||
verdict = ((struct ebt_standard_target *)t)->verdict;
|
verdict = ((struct ebt_standard_target *)t)->verdict;
|
||||||
else {
|
else {
|
||||||
tgpar.target = t->u.target;
|
acpar.target = t->u.target;
|
||||||
tgpar.targinfo = t->data;
|
acpar.targinfo = t->data;
|
||||||
verdict = t->u.target->target(skb, &tgpar);
|
verdict = t->u.target->target(skb, &acpar);
|
||||||
}
|
}
|
||||||
if (verdict == EBT_ACCEPT) {
|
if (verdict == EBT_ACCEPT) {
|
||||||
read_unlock_bh(&table->lock);
|
read_unlock_bh(&table->lock);
|
||||||
|
@ -265,7 +265,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
|
|||||||
const char *indev, *outdev;
|
const char *indev, *outdev;
|
||||||
void *table_base;
|
void *table_base;
|
||||||
const struct xt_table_info *private;
|
const struct xt_table_info *private;
|
||||||
struct xt_target_param tgpar;
|
struct xt_action_param acpar;
|
||||||
|
|
||||||
if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
|
if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
@ -280,10 +280,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
|
|||||||
e = get_entry(table_base, private->hook_entry[hook]);
|
e = get_entry(table_base, private->hook_entry[hook]);
|
||||||
back = get_entry(table_base, private->underflow[hook]);
|
back = get_entry(table_base, private->underflow[hook]);
|
||||||
|
|
||||||
tgpar.in = in;
|
acpar.in = in;
|
||||||
tgpar.out = out;
|
acpar.out = out;
|
||||||
tgpar.hooknum = hook;
|
acpar.hooknum = hook;
|
||||||
tgpar.family = NFPROTO_ARP;
|
acpar.family = NFPROTO_ARP;
|
||||||
|
|
||||||
arp = arp_hdr(skb);
|
arp = arp_hdr(skb);
|
||||||
do {
|
do {
|
||||||
@ -333,9 +333,9 @@ unsigned int arpt_do_table(struct sk_buff *skb,
|
|||||||
/* Targets which reenter must return
|
/* Targets which reenter must return
|
||||||
* abs. verdicts
|
* abs. verdicts
|
||||||
*/
|
*/
|
||||||
tgpar.target = t->u.kernel.target;
|
acpar.target = t->u.kernel.target;
|
||||||
tgpar.targinfo = t->data;
|
acpar.targinfo = t->data;
|
||||||
verdict = t->u.kernel.target->target(skb, &tgpar);
|
verdict = t->u.kernel.target->target(skb, &acpar);
|
||||||
|
|
||||||
/* Target might have changed stuff. */
|
/* Target might have changed stuff. */
|
||||||
arp = arp_hdr(skb);
|
arp = arp_hdr(skb);
|
||||||
|
@ -316,8 +316,7 @@ ipt_do_table(struct sk_buff *skb,
|
|||||||
struct ipt_entry *e, **jumpstack;
|
struct ipt_entry *e, **jumpstack;
|
||||||
unsigned int *stackptr, origptr, cpu;
|
unsigned int *stackptr, origptr, cpu;
|
||||||
const struct xt_table_info *private;
|
const struct xt_table_info *private;
|
||||||
struct xt_match_param mtpar;
|
struct xt_action_param acpar;
|
||||||
struct xt_target_param tgpar;
|
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
ip = ip_hdr(skb);
|
ip = ip_hdr(skb);
|
||||||
@ -329,13 +328,13 @@ ipt_do_table(struct sk_buff *skb,
|
|||||||
* things we don't know, ie. tcp syn flag or ports). If the
|
* things we don't know, ie. tcp syn flag or ports). If the
|
||||||
* rule is also a fragment-specific rule, non-fragments won't
|
* rule is also a fragment-specific rule, non-fragments won't
|
||||||
* match it. */
|
* match it. */
|
||||||
mtpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
|
acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
|
||||||
mtpar.thoff = ip_hdrlen(skb);
|
acpar.thoff = ip_hdrlen(skb);
|
||||||
mtpar.hotdrop = &hotdrop;
|
acpar.hotdrop = &hotdrop;
|
||||||
mtpar.in = tgpar.in = in;
|
acpar.in = in;
|
||||||
mtpar.out = tgpar.out = out;
|
acpar.out = out;
|
||||||
mtpar.family = tgpar.family = NFPROTO_IPV4;
|
acpar.family = NFPROTO_IPV4;
|
||||||
mtpar.hooknum = tgpar.hooknum = hook;
|
acpar.hooknum = hook;
|
||||||
|
|
||||||
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
|
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
|
||||||
xt_info_rdlock_bh();
|
xt_info_rdlock_bh();
|
||||||
@ -358,16 +357,16 @@ ipt_do_table(struct sk_buff *skb,
|
|||||||
|
|
||||||
IP_NF_ASSERT(e);
|
IP_NF_ASSERT(e);
|
||||||
if (!ip_packet_match(ip, indev, outdev,
|
if (!ip_packet_match(ip, indev, outdev,
|
||||||
&e->ip, mtpar.fragoff)) {
|
&e->ip, acpar.fragoff)) {
|
||||||
no_match:
|
no_match:
|
||||||
e = ipt_next_entry(e);
|
e = ipt_next_entry(e);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
xt_ematch_foreach(ematch, e) {
|
xt_ematch_foreach(ematch, e) {
|
||||||
mtpar.match = ematch->u.kernel.match;
|
acpar.match = ematch->u.kernel.match;
|
||||||
mtpar.matchinfo = ematch->data;
|
acpar.matchinfo = ematch->data;
|
||||||
if (!mtpar.match->match(skb, &mtpar))
|
if (!acpar.match->match(skb, &acpar))
|
||||||
goto no_match;
|
goto no_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,11 +421,10 @@ ipt_do_table(struct sk_buff *skb,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tgpar.target = t->u.kernel.target;
|
acpar.target = t->u.kernel.target;
|
||||||
tgpar.targinfo = t->data;
|
acpar.targinfo = t->data;
|
||||||
|
|
||||||
|
verdict = t->u.kernel.target->target(skb, &acpar);
|
||||||
verdict = t->u.kernel.target->target(skb, &tgpar);
|
|
||||||
/* Target might have changed stuff. */
|
/* Target might have changed stuff. */
|
||||||
ip = ip_hdr(skb);
|
ip = ip_hdr(skb);
|
||||||
if (verdict == IPT_CONTINUE)
|
if (verdict == IPT_CONTINUE)
|
||||||
|
@ -345,8 +345,7 @@ ip6t_do_table(struct sk_buff *skb,
|
|||||||
struct ip6t_entry *e, **jumpstack;
|
struct ip6t_entry *e, **jumpstack;
|
||||||
unsigned int *stackptr, origptr, cpu;
|
unsigned int *stackptr, origptr, cpu;
|
||||||
const struct xt_table_info *private;
|
const struct xt_table_info *private;
|
||||||
struct xt_match_param mtpar;
|
struct xt_action_param acpar;
|
||||||
struct xt_target_param tgpar;
|
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
indev = in ? in->name : nulldevname;
|
indev = in ? in->name : nulldevname;
|
||||||
@ -357,11 +356,11 @@ ip6t_do_table(struct sk_buff *skb,
|
|||||||
* things we don't know, ie. tcp syn flag or ports). If the
|
* things we don't know, ie. tcp syn flag or ports). If the
|
||||||
* rule is also a fragment-specific rule, non-fragments won't
|
* rule is also a fragment-specific rule, non-fragments won't
|
||||||
* match it. */
|
* match it. */
|
||||||
mtpar.hotdrop = &hotdrop;
|
acpar.hotdrop = &hotdrop;
|
||||||
mtpar.in = tgpar.in = in;
|
acpar.in = in;
|
||||||
mtpar.out = tgpar.out = out;
|
acpar.out = out;
|
||||||
mtpar.family = tgpar.family = NFPROTO_IPV6;
|
acpar.family = NFPROTO_IPV6;
|
||||||
mtpar.hooknum = tgpar.hooknum = hook;
|
acpar.hooknum = hook;
|
||||||
|
|
||||||
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
|
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
|
||||||
|
|
||||||
@ -381,16 +380,16 @@ ip6t_do_table(struct sk_buff *skb,
|
|||||||
|
|
||||||
IP_NF_ASSERT(e);
|
IP_NF_ASSERT(e);
|
||||||
if (!ip6_packet_match(skb, indev, outdev, &e->ipv6,
|
if (!ip6_packet_match(skb, indev, outdev, &e->ipv6,
|
||||||
&mtpar.thoff, &mtpar.fragoff, &hotdrop)) {
|
&acpar.thoff, &acpar.fragoff, &hotdrop)) {
|
||||||
no_match:
|
no_match:
|
||||||
e = ip6t_next_entry(e);
|
e = ip6t_next_entry(e);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
xt_ematch_foreach(ematch, e) {
|
xt_ematch_foreach(ematch, e) {
|
||||||
mtpar.match = ematch->u.kernel.match;
|
acpar.match = ematch->u.kernel.match;
|
||||||
mtpar.matchinfo = ematch->data;
|
acpar.matchinfo = ematch->data;
|
||||||
if (!mtpar.match->match(skb, &mtpar))
|
if (!acpar.match->match(skb, &acpar))
|
||||||
goto no_match;
|
goto no_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,10 +438,10 @@ ip6t_do_table(struct sk_buff *skb,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tgpar.target = t->u.kernel.target;
|
acpar.target = t->u.kernel.target;
|
||||||
tgpar.targinfo = t->data;
|
acpar.targinfo = t->data;
|
||||||
|
|
||||||
verdict = t->u.kernel.target->target(skb, &tgpar);
|
verdict = t->u.kernel.target->target(skb, &acpar);
|
||||||
if (verdict == IP6T_CONTINUE)
|
if (verdict == IP6T_CONTINUE)
|
||||||
e = ip6t_next_entry(e);
|
e = ip6t_next_entry(e);
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user