diff options
author | Jan Engelhardt <jengelh@medozas.de> | 2008-10-08 05:35:18 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2008-10-08 05:35:18 -0400 |
commit | f7108a20dee44e5bb037f9e48f6a207b42e6ae1c (patch) | |
tree | bfc741548cdf416a59a89d89a20ba2cbdc8e988e /net/ipv4 | |
parent | c2df73de246ae75705af8ceed4f385b261dea108 (diff) |
netfilter: xtables: move extension arguments into compound structure (1/6)
The function signatures for Xtables extensions have grown over time.
It involves a lot of typing/replication, and also a bit of stack space
even if they are not used. Realize an NFWS2008 idea and pack them into
structs. The skb remains outside of the struct so gcc can continue to
apply its optimizations.
This patch does this for match extensions' match functions.
A few ambiguities have also been addressed. The "offset" parameter for
example has been renamed to "fragoff" (there are so many different
offsets already) and "protoff" to "thoff" (there is more than just one
protocol here, so clarify).
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 46 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_addrtype.c | 18 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ah.c | 14 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ecn.c | 9 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ttl.c | 7 |
5 files changed, 36 insertions, 58 deletions
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index b4c74a7a807c..99fdb59454fd 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -186,16 +186,14 @@ ipt_error(struct sk_buff *skb, | |||
186 | 186 | ||
187 | /* Performance critical - called for every packet */ | 187 | /* Performance critical - called for every packet */ |
188 | static inline bool | 188 | static inline bool |
189 | do_match(struct ipt_entry_match *m, | 189 | do_match(struct ipt_entry_match *m, const struct sk_buff *skb, |
190 | const struct sk_buff *skb, | 190 | struct xt_match_param *par) |
191 | const struct net_device *in, | ||
192 | const struct net_device *out, | ||
193 | int offset, | ||
194 | bool *hotdrop) | ||
195 | { | 191 | { |
192 | par->match = m->u.kernel.match; | ||
193 | par->matchinfo = m->data; | ||
194 | |||
196 | /* Stop iteration if it doesn't match */ | 195 | /* Stop iteration if it doesn't match */ |
197 | if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, | 196 | if (!m->u.kernel.match->match(skb, par)) |
198 | offset, ip_hdrlen(skb), hotdrop)) | ||
199 | return true; | 197 | return true; |
200 | else | 198 | else |
201 | return false; | 199 | return false; |
@@ -326,7 +324,6 @@ ipt_do_table(struct sk_buff *skb, | |||
326 | struct xt_table *table) | 324 | struct xt_table *table) |
327 | { | 325 | { |
328 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); | 326 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
329 | u_int16_t offset; | ||
330 | const struct iphdr *ip; | 327 | const struct iphdr *ip; |
331 | u_int16_t datalen; | 328 | u_int16_t datalen; |
332 | bool hotdrop = false; | 329 | bool hotdrop = false; |
@@ -336,6 +333,7 @@ ipt_do_table(struct sk_buff *skb, | |||
336 | void *table_base; | 333 | void *table_base; |
337 | struct ipt_entry *e, *back; | 334 | struct ipt_entry *e, *back; |
338 | struct xt_table_info *private; | 335 | struct xt_table_info *private; |
336 | struct xt_match_param mtpar; | ||
339 | 337 | ||
340 | /* Initialization */ | 338 | /* Initialization */ |
341 | ip = ip_hdr(skb); | 339 | ip = ip_hdr(skb); |
@@ -348,7 +346,11 @@ ipt_do_table(struct sk_buff *skb, | |||
348 | * things we don't know, ie. tcp syn flag or ports). If the | 346 | * things we don't know, ie. tcp syn flag or ports). If the |
349 | * rule is also a fragment-specific rule, non-fragments won't | 347 | * rule is also a fragment-specific rule, non-fragments won't |
350 | * match it. */ | 348 | * match it. */ |
351 | offset = ntohs(ip->frag_off) & IP_OFFSET; | 349 | mtpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; |
350 | mtpar.thoff = ip_hdrlen(skb); | ||
351 | mtpar.hotdrop = &hotdrop; | ||
352 | mtpar.in = in; | ||
353 | mtpar.out = out; | ||
352 | 354 | ||
353 | read_lock_bh(&table->lock); | 355 | read_lock_bh(&table->lock); |
354 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 356 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
@@ -362,12 +364,11 @@ ipt_do_table(struct sk_buff *skb, | |||
362 | do { | 364 | do { |
363 | IP_NF_ASSERT(e); | 365 | IP_NF_ASSERT(e); |
364 | IP_NF_ASSERT(back); | 366 | IP_NF_ASSERT(back); |
365 | if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) { | 367 | if (ip_packet_match(ip, indev, outdev, |
368 | &e->ip, mtpar.fragoff)) { | ||
366 | struct ipt_entry_target *t; | 369 | struct ipt_entry_target *t; |
367 | 370 | ||
368 | if (IPT_MATCH_ITERATE(e, do_match, | 371 | if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) |
369 | skb, in, out, | ||
370 | offset, &hotdrop) != 0) | ||
371 | goto no_match; | 372 | goto no_match; |
372 | 373 | ||
373 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); | 374 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); |
@@ -2116,30 +2117,23 @@ icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code, | |||
2116 | } | 2117 | } |
2117 | 2118 | ||
2118 | static bool | 2119 | static bool |
2119 | icmp_match(const struct sk_buff *skb, | 2120 | icmp_match(const struct sk_buff *skb, const struct xt_match_param *par) |
2120 | const struct net_device *in, | ||
2121 | const struct net_device *out, | ||
2122 | const struct xt_match *match, | ||
2123 | const void *matchinfo, | ||
2124 | int offset, | ||
2125 | unsigned int protoff, | ||
2126 | bool *hotdrop) | ||
2127 | { | 2121 | { |
2128 | const struct icmphdr *ic; | 2122 | const struct icmphdr *ic; |
2129 | struct icmphdr _icmph; | 2123 | struct icmphdr _icmph; |
2130 | const struct ipt_icmp *icmpinfo = matchinfo; | 2124 | const struct ipt_icmp *icmpinfo = par->matchinfo; |
2131 | 2125 | ||
2132 | /* Must not be a fragment. */ | 2126 | /* Must not be a fragment. */ |
2133 | if (offset) | 2127 | if (par->fragoff != 0) |
2134 | return false; | 2128 | return false; |
2135 | 2129 | ||
2136 | ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); | 2130 | ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph); |
2137 | if (ic == NULL) { | 2131 | if (ic == NULL) { |
2138 | /* We've been asked to examine this packet, and we | 2132 | /* We've been asked to examine this packet, and we |
2139 | * can't. Hence, no choice but to drop. | 2133 | * can't. Hence, no choice but to drop. |
2140 | */ | 2134 | */ |
2141 | duprintf("Dropping evil ICMP tinygram.\n"); | 2135 | duprintf("Dropping evil ICMP tinygram.\n"); |
2142 | *hotdrop = true; | 2136 | *par->hotdrop = true; |
2143 | return false; | 2137 | return false; |
2144 | } | 2138 | } |
2145 | 2139 | ||
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index 2c9d88a6c838..e60995e4c20c 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c | |||
@@ -30,12 +30,9 @@ static inline bool match_type(const struct net_device *dev, __be32 addr, | |||
30 | } | 30 | } |
31 | 31 | ||
32 | static bool | 32 | static bool |
33 | addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in, | 33 | addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par) |
34 | const struct net_device *out, const struct xt_match *match, | ||
35 | const void *matchinfo, int offset, unsigned int protoff, | ||
36 | bool *hotdrop) | ||
37 | { | 34 | { |
38 | const struct ipt_addrtype_info *info = matchinfo; | 35 | const struct ipt_addrtype_info *info = par->matchinfo; |
39 | const struct iphdr *iph = ip_hdr(skb); | 36 | const struct iphdr *iph = ip_hdr(skb); |
40 | bool ret = true; | 37 | bool ret = true; |
41 | 38 | ||
@@ -50,20 +47,17 @@ addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in, | |||
50 | } | 47 | } |
51 | 48 | ||
52 | static bool | 49 | static bool |
53 | addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in, | 50 | addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) |
54 | const struct net_device *out, const struct xt_match *match, | ||
55 | const void *matchinfo, int offset, unsigned int protoff, | ||
56 | bool *hotdrop) | ||
57 | { | 51 | { |
58 | const struct ipt_addrtype_info_v1 *info = matchinfo; | 52 | const struct ipt_addrtype_info_v1 *info = par->matchinfo; |
59 | const struct iphdr *iph = ip_hdr(skb); | 53 | const struct iphdr *iph = ip_hdr(skb); |
60 | const struct net_device *dev = NULL; | 54 | const struct net_device *dev = NULL; |
61 | bool ret = true; | 55 | bool ret = true; |
62 | 56 | ||
63 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) | 57 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) |
64 | dev = in; | 58 | dev = par->in; |
65 | else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) | 59 | else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) |
66 | dev = out; | 60 | dev = par->out; |
67 | 61 | ||
68 | if (info->source) | 62 | if (info->source) |
69 | ret &= match_type(dev, iph->saddr, info->source) ^ | 63 | ret &= match_type(dev, iph->saddr, info->source) ^ |
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c index e2e993edd665..2fce19ef4f3f 100644 --- a/net/ipv4/netfilter/ipt_ah.c +++ b/net/ipv4/netfilter/ipt_ah.c | |||
@@ -36,27 +36,23 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert) | |||
36 | return r; | 36 | return r; |
37 | } | 37 | } |
38 | 38 | ||
39 | static bool | 39 | static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
40 | ah_mt(const struct sk_buff *skb, const struct net_device *in, | ||
41 | const struct net_device *out, const struct xt_match *match, | ||
42 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
43 | { | 40 | { |
44 | struct ip_auth_hdr _ahdr; | 41 | struct ip_auth_hdr _ahdr; |
45 | const struct ip_auth_hdr *ah; | 42 | const struct ip_auth_hdr *ah; |
46 | const struct ipt_ah *ahinfo = matchinfo; | 43 | const struct ipt_ah *ahinfo = par->matchinfo; |
47 | 44 | ||
48 | /* Must not be a fragment. */ | 45 | /* Must not be a fragment. */ |
49 | if (offset) | 46 | if (par->fragoff != 0) |
50 | return false; | 47 | return false; |
51 | 48 | ||
52 | ah = skb_header_pointer(skb, protoff, | 49 | ah = skb_header_pointer(skb, par->thoff, sizeof(_ahdr), &_ahdr); |
53 | sizeof(_ahdr), &_ahdr); | ||
54 | if (ah == NULL) { | 50 | if (ah == NULL) { |
55 | /* We've been asked to examine this packet, and we | 51 | /* We've been asked to examine this packet, and we |
56 | * can't. Hence, no choice but to drop. | 52 | * can't. Hence, no choice but to drop. |
57 | */ | 53 | */ |
58 | duprintf("Dropping evil AH tinygram.\n"); | 54 | duprintf("Dropping evil AH tinygram.\n"); |
59 | *hotdrop = true; | 55 | *par->hotdrop = true; |
60 | return 0; | 56 | return 0; |
61 | } | 57 | } |
62 | 58 | ||
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c index 2c45b4be7c3c..069154631508 100644 --- a/net/ipv4/netfilter/ipt_ecn.c +++ b/net/ipv4/netfilter/ipt_ecn.c | |||
@@ -67,12 +67,9 @@ static inline bool match_tcp(const struct sk_buff *skb, | |||
67 | return true; | 67 | return true; |
68 | } | 68 | } |
69 | 69 | ||
70 | static bool | 70 | static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
71 | ecn_mt(const struct sk_buff *skb, const struct net_device *in, | ||
72 | const struct net_device *out, const struct xt_match *match, | ||
73 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
74 | { | 71 | { |
75 | const struct ipt_ecn_info *info = matchinfo; | 72 | const struct ipt_ecn_info *info = par->matchinfo; |
76 | 73 | ||
77 | if (info->operation & IPT_ECN_OP_MATCH_IP) | 74 | if (info->operation & IPT_ECN_OP_MATCH_IP) |
78 | if (!match_ip(skb, info)) | 75 | if (!match_ip(skb, info)) |
@@ -81,7 +78,7 @@ ecn_mt(const struct sk_buff *skb, const struct net_device *in, | |||
81 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { | 78 | if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { |
82 | if (ip_hdr(skb)->protocol != IPPROTO_TCP) | 79 | if (ip_hdr(skb)->protocol != IPPROTO_TCP) |
83 | return false; | 80 | return false; |
84 | if (!match_tcp(skb, info, hotdrop)) | 81 | if (!match_tcp(skb, info, par->hotdrop)) |
85 | return false; | 82 | return false; |
86 | } | 83 | } |
87 | 84 | ||
diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c index d4c3fdc2a79f..297f1cbf4ff5 100644 --- a/net/ipv4/netfilter/ipt_ttl.c +++ b/net/ipv4/netfilter/ipt_ttl.c | |||
@@ -18,12 +18,9 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | |||
18 | MODULE_DESCRIPTION("Xtables: IPv4 TTL field match"); | 18 | MODULE_DESCRIPTION("Xtables: IPv4 TTL field match"); |
19 | MODULE_LICENSE("GPL"); | 19 | MODULE_LICENSE("GPL"); |
20 | 20 | ||
21 | static bool | 21 | static bool ttl_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
22 | ttl_mt(const struct sk_buff *skb, const struct net_device *in, | ||
23 | const struct net_device *out, const struct xt_match *match, | ||
24 | const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop) | ||
25 | { | 22 | { |
26 | const struct ipt_ttl_info *info = matchinfo; | 23 | const struct ipt_ttl_info *info = par->matchinfo; |
27 | const u8 ttl = ip_hdr(skb)->ttl; | 24 | const u8 ttl = ip_hdr(skb)->ttl; |
28 | 25 | ||
29 | switch (info->mode) { | 26 | switch (info->mode) { |