aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2005-07-05 17:10:21 -0400
committerDavid S. Miller <davem@davemloft.net>2005-07-05 17:10:21 -0400
commit0b05b2a49e430220876f8faa7e4778dc7497033c (patch)
treea6b0491ad0986cf2d102f7aba954a5a56cdfa658
parent6935d46c2da64aa032a557374c95336e265cd7ef (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>
-rw-r--r--net/core/filter.c90
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 */
39static u8 *load_pointer(struct sk_buff *skb, int k) 39static 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
53static 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
65int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) 77int 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;
214load_b: 201load_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;