diff options
author | Patrick McHardy <kaber@trash.net> | 2005-07-05 17:10:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-07-05 17:10:21 -0400 |
commit | 0b05b2a49e430220876f8faa7e4778dc7497033c (patch) | |
tree | a6b0491ad0986cf2d102f7aba954a5a56cdfa658 /net | |
parent | 6935d46c2da64aa032a557374c95336e265cd7ef (diff) |
[NET]: Consolidate common code in net/core/filter.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/filter.c | 90 |
1 files changed, 33 insertions, 57 deletions
diff --git a/net/core/filter.c b/net/core/filter.c index e1267b465def..3923428a840f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/filter.h> | 36 | #include <linux/filter.h> |
37 | 37 | ||
38 | /* No hurry in this branch */ | 38 | /* No hurry in this branch */ |
39 | static u8 *load_pointer(struct sk_buff *skb, int k) | 39 | static void *__load_pointer(struct sk_buff *skb, int k) |
40 | { | 40 | { |
41 | u8 *ptr = NULL; | 41 | u8 *ptr = NULL; |
42 | 42 | ||
@@ -50,6 +50,18 @@ static u8 *load_pointer(struct sk_buff *skb, int k) | |||
50 | return NULL; | 50 | return NULL; |
51 | } | 51 | } |
52 | 52 | ||
53 | static inline void *load_pointer(struct sk_buff *skb, int k, | ||
54 | unsigned int size, void *buffer) | ||
55 | { | ||
56 | if (k >= 0) | ||
57 | return skb_header_pointer(skb, k, size, buffer); | ||
58 | else { | ||
59 | if (k >= SKF_AD_OFF) | ||
60 | return NULL; | ||
61 | return __load_pointer(skb, k); | ||
62 | } | ||
63 | } | ||
64 | |||
53 | /** | 65 | /** |
54 | * sk_run_filter - run a filter on a socket | 66 | * sk_run_filter - run a filter on a socket |
55 | * @skb: buffer to run the filter on | 67 | * @skb: buffer to run the filter on |
@@ -64,15 +76,16 @@ static u8 *load_pointer(struct sk_buff *skb, int k) | |||
64 | 76 | ||
65 | int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) | 77 | int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) |
66 | { | 78 | { |
67 | unsigned char *data = skb->data; | ||
68 | /* len is UNSIGNED. Byte wide insns relies only on implicit | 79 | /* len is UNSIGNED. Byte wide insns relies only on implicit |
69 | type casts to prevent reading arbitrary memory locations. | 80 | type casts to prevent reading arbitrary memory locations. |
70 | */ | 81 | */ |
71 | unsigned int len = skb->len-skb->data_len; | 82 | unsigned int len = skb->len-skb->data_len; |
72 | struct sock_filter *fentry; /* We walk down these */ | 83 | struct sock_filter *fentry; /* We walk down these */ |
84 | void *ptr; | ||
73 | u32 A = 0; /* Accumulator */ | 85 | u32 A = 0; /* Accumulator */ |
74 | u32 X = 0; /* Index Register */ | 86 | u32 X = 0; /* Index Register */ |
75 | u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */ | 87 | u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */ |
88 | u32 tmp; | ||
76 | int k; | 89 | int k; |
77 | int pc; | 90 | int pc; |
78 | 91 | ||
@@ -168,67 +181,28 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) | |||
168 | case BPF_LD|BPF_W|BPF_ABS: | 181 | case BPF_LD|BPF_W|BPF_ABS: |
169 | k = fentry->k; | 182 | k = fentry->k; |
170 | load_w: | 183 | load_w: |
171 | if (k < 0) { | 184 | ptr = load_pointer(skb, k, 4, &tmp); |
172 | u8 *ptr; | 185 | if (ptr != NULL) { |
173 | 186 | A = ntohl(*(u32 *)ptr); | |
174 | if (k >= SKF_AD_OFF) | 187 | continue; |
175 | break; | ||
176 | ptr = load_pointer(skb, k); | ||
177 | if (ptr) { | ||
178 | A = ntohl(*(u32*)ptr); | ||
179 | continue; | ||
180 | } | ||
181 | } else { | ||
182 | u32 _tmp, *p; | ||
183 | p = skb_header_pointer(skb, k, 4, &_tmp); | ||
184 | if (p != NULL) { | ||
185 | A = ntohl(*p); | ||
186 | continue; | ||
187 | } | ||
188 | } | 188 | } |
189 | return 0; | 189 | return 0; |
190 | case BPF_LD|BPF_H|BPF_ABS: | 190 | case BPF_LD|BPF_H|BPF_ABS: |
191 | k = fentry->k; | 191 | k = fentry->k; |
192 | load_h: | 192 | load_h: |
193 | if (k < 0) { | 193 | ptr = load_pointer(skb, k, 2, &tmp); |
194 | u8 *ptr; | 194 | if (ptr != NULL) { |
195 | 195 | A = ntohs(*(u16 *)ptr); | |
196 | if (k >= SKF_AD_OFF) | 196 | continue; |
197 | break; | ||
198 | ptr = load_pointer(skb, k); | ||
199 | if (ptr) { | ||
200 | A = ntohs(*(u16*)ptr); | ||
201 | continue; | ||
202 | } | ||
203 | } else { | ||
204 | u16 _tmp, *p; | ||
205 | p = skb_header_pointer(skb, k, 2, &_tmp); | ||
206 | if (p != NULL) { | ||
207 | A = ntohs(*p); | ||
208 | continue; | ||
209 | } | ||
210 | } | 197 | } |
211 | return 0; | 198 | return 0; |
212 | case BPF_LD|BPF_B|BPF_ABS: | 199 | case BPF_LD|BPF_B|BPF_ABS: |
213 | k = fentry->k; | 200 | k = fentry->k; |
214 | load_b: | 201 | load_b: |
215 | if (k < 0) { | 202 | ptr = load_pointer(skb, k, 1, &tmp); |
216 | u8 *ptr; | 203 | if (ptr != NULL) { |
217 | 204 | A = *(u8 *)ptr; | |
218 | if (k >= SKF_AD_OFF) | 205 | continue; |
219 | break; | ||
220 | ptr = load_pointer(skb, k); | ||
221 | if (ptr) { | ||
222 | A = *ptr; | ||
223 | continue; | ||
224 | } | ||
225 | } else { | ||
226 | u8 _tmp, *p; | ||
227 | p = skb_header_pointer(skb, k, 1, &_tmp); | ||
228 | if (p != NULL) { | ||
229 | A = *p; | ||
230 | continue; | ||
231 | } | ||
232 | } | 206 | } |
233 | return 0; | 207 | return 0; |
234 | case BPF_LD|BPF_W|BPF_LEN: | 208 | case BPF_LD|BPF_W|BPF_LEN: |
@@ -247,10 +221,12 @@ load_b: | |||
247 | k = X + fentry->k; | 221 | k = X + fentry->k; |
248 | goto load_b; | 222 | goto load_b; |
249 | case BPF_LDX|BPF_B|BPF_MSH: | 223 | case BPF_LDX|BPF_B|BPF_MSH: |
250 | if (fentry->k >= len) | 224 | ptr = load_pointer(skb, fentry->k, 1, &tmp); |
251 | return 0; | 225 | if (ptr != NULL) { |
252 | X = (data[fentry->k] & 0xf) << 2; | 226 | X = (*(u8 *)ptr & 0xf) << 2; |
253 | continue; | 227 | continue; |
228 | } | ||
229 | return 0; | ||
254 | case BPF_LD|BPF_IMM: | 230 | case BPF_LD|BPF_IMM: |
255 | A = fentry->k; | 231 | A = fentry->k; |
256 | continue; | 232 | continue; |