aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@medozas.de>2008-10-08 05:35:18 -0400
committerPatrick McHardy <kaber@trash.net>2008-10-08 05:35:18 -0400
commitf7108a20dee44e5bb037f9e48f6a207b42e6ae1c (patch)
treebfc741548cdf416a59a89d89a20ba2cbdc8e988e /net/ipv4
parentc2df73de246ae75705af8ceed4f385b261dea108 (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.c46
-rw-r--r--net/ipv4/netfilter/ipt_addrtype.c18
-rw-r--r--net/ipv4/netfilter/ipt_ah.c14
-rw-r--r--net/ipv4/netfilter/ipt_ecn.c9
-rw-r--r--net/ipv4/netfilter/ipt_ttl.c7
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 */
188static inline bool 188static inline bool
189do_match(struct ipt_entry_match *m, 189do_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
2118static bool 2119static bool
2119icmp_match(const struct sk_buff *skb, 2120icmp_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
32static bool 32static bool
33addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in, 33addrtype_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
52static bool 49static bool
53addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in, 50addrtype_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
39static bool 39static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par)
40ah_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
70static bool 70static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par)
71ecn_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>");
18MODULE_DESCRIPTION("Xtables: IPv4 TTL field match"); 18MODULE_DESCRIPTION("Xtables: IPv4 TTL field match");
19MODULE_LICENSE("GPL"); 19MODULE_LICENSE("GPL");
20 20
21static bool 21static bool ttl_mt(const struct sk_buff *skb, const struct xt_match_param *par)
22ttl_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) {