1 /*
2 * Copyright (c) 2001 - 2003
3 * NetGroup, Politecnico di Torino (Italy)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the Politecnico di Torino nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33 #include <GlobalConst.h>
34
35 #include "tme.h"
36
37 /* resizes extended memory */
init_extended_memory(uint32 size,MEM_TYPE * mem_ex)38 uint32 init_extended_memory(uint32 size, MEM_TYPE *mem_ex)
39 {
40 uint8 *tmp;
41
42 if ((mem_ex==NULL)||(mem_ex->buffer==NULL)||(size==0))
43 return TME_ERROR; /* awfully never reached!!!! */
44
45 tmp=mem_ex->buffer;
46 mem_ex->buffer=NULL;
47 FREE_MEMORY(tmp);
48
49 ALLOCATE_MEMORY(tmp,uint8,size);
50 if (tmp==NULL)
51 return TME_ERROR; /* no memory */
52
53 mem_ex->size=size;
54 mem_ex->buffer=tmp;
55 return TME_SUCCESS;
56
57 }
58
59 /* activates a block of the TME */
set_active_tme_block(TME_CORE * tme,uint32 block)60 uint32 set_active_tme_block(TME_CORE *tme, uint32 block)
61 {
62
63 if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block)))
64 return TME_ERROR;
65 tme->active=block;
66 tme->working=block;
67 return TME_SUCCESS;
68
69 }
70
71 /* simply inserts default values in a TME block */
72 /* it DOESN'T initialize the block in the core!! */
73 /* FIXME default values are defined at compile time, */
74 /* it will be useful to store them in the registry */
init_tme_block(TME_CORE * tme,uint32 block)75 uint32 init_tme_block(TME_CORE *tme, uint32 block)
76 {
77
78 TME_DATA *data;
79 if (block>=MAX_TME_DATA_BLOCKS)
80 return TME_ERROR;
81 data=&(tme->block_data[block]);
82 tme->working=block;
83
84 ZERO_MEMORY(data,sizeof(TME_DATA));
85
86 /* entries in LUT */
87 data->lut_entries=TME_LUT_ENTRIES_DEFAULT;
88 /* blocks */
89 data->shared_memory_blocks=TME_SHARED_MEMORY_BLOCKS_DEFAULT;
90 /* block size */
91 data->block_size=TME_BLOCK_SIZE_DEFAULT;
92 /* lookup function */
93 data->lookup_code=lut_fcn_mapper(TME_LOOKUP_CODE_DEFAULT);
94 /* rehashing value */
95 data->rehashing_value=TME_REHASHING_VALUE_DEFAULT;
96 /* out lut function */
97 data->out_lut_exec=TME_OUT_LUT_EXEC_DEFAULT;
98 /* default function */
99 data->default_exec=TME_DEFAULT_EXEC_DEFAULT;
100 /* extra segment size */
101 data->extra_segment_size=TME_EXTRA_SEGMENT_SIZE_DEFAULT;
102
103
104 data->enable_deletion=FALSE;
105 data->last_read.tv_sec=0;
106 data->last_read.tv_usec=0;
107 return TME_SUCCESS;
108
109 }
110 /* it validates a TME block and */
111 /* (on OK) inserts the block in the core */
validate_tme_block(MEM_TYPE * mem_ex,TME_CORE * tme,uint32 block,uint32 mem_ex_offset)112 uint32 validate_tme_block(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 block, uint32 mem_ex_offset)
113 {
114 uint32 required_memory;
115 uint8 *base=mem_ex_offset+mem_ex->buffer;
116 TME_DATA *data;
117
118 /* FIXME soluzione un po' posticcia... */
119 if (mem_ex_offset==0)
120 return TME_ERROR;
121
122 if (block>=MAX_TME_DATA_BLOCKS)
123 return TME_ERROR;
124 data=&tme->block_data[block];
125
126 if (data->lut_entries==0)
127 return TME_ERROR;
128
129 if (data->key_len==0)
130 return TME_ERROR;
131
132 if (data->shared_memory_blocks==0)
133 return TME_ERROR;
134
135 if (data->block_size==0)
136 return TME_ERROR;
137
138 /* checks if the lookup function is valid */
139 if (data->lookup_code==NULL)
140 return TME_ERROR;
141
142 /* checks if the out lut exec function is valid */
143 if (exec_fcn_mapper(data->out_lut_exec)==NULL)
144 return TME_ERROR;
145
146 /* checks if the default exec function is valid */
147 if (exec_fcn_mapper(data->default_exec)==NULL)
148 return TME_ERROR;
149
150 /* let's calculate memory needed */
151 required_memory=data->lut_entries*sizeof(RECORD); /*LUT*/
152 required_memory+=data->block_size*data->shared_memory_blocks; /*shared segment*/
153 required_memory+=data->extra_segment_size; /*extra segment*/
154
155 if (required_memory>(mem_ex->size-mem_ex_offset))
156 return TME_ERROR; /*not enough memory*/
157
158 /* the TME block can be initialized */
159 ZERO_MEMORY(base,required_memory);
160
161 data->lut_base_address=base;
162
163 data->shared_memory_base_address=
164 data->lut_base_address+
165 data->lut_entries*sizeof(RECORD);
166
167 data->extra_segment_base_address=
168 data->shared_memory_base_address+
169 data->block_size*data->shared_memory_blocks;
170 data->filled_blocks=1;
171 VALIDATE(tme->validated_blocks,block);
172 tme->active=block;
173 tme->working=block;
174 return TME_SUCCESS;
175 }
176
177 /* I/F between the bpf machine and the callbacks, just some checks */
lookup_frontend(MEM_TYPE * mem_ex,TME_CORE * tme,uint32 mem_ex_offset,struct time_conv * time_ref)178 uint32 lookup_frontend(MEM_TYPE *mem_ex, TME_CORE *tme,uint32 mem_ex_offset, struct time_conv *time_ref)
179 {
180 if (tme->active==TME_NONE_ACTIVE)
181 return TME_FALSE;
182
183 return (tme->block_data[tme->active].lookup_code)(mem_ex_offset+mem_ex->buffer,&tme->block_data[tme->active],mem_ex, time_ref);
184 }
185
186 /* I/F between the bpf machine and the callbacks, just some checks */
execute_frontend(MEM_TYPE * mem_ex,TME_CORE * tme,uint32 pkt_size,uint32 offset)187 uint32 execute_frontend(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 pkt_size, uint32 offset)
188 {
189
190 exec_fcn tmp;
191 TME_DATA *data;
192 uint8 *block;
193 uint8 *mem_data;
194
195 if (tme->active==TME_NONE_ACTIVE)
196 return TME_ERROR;
197
198 data=&tme->block_data[tme->active];
199
200 if (data->last_found==NULL)
201 { /*out lut exec */
202 tmp=exec_fcn_mapper(data->out_lut_exec);
203 block=data->shared_memory_base_address;
204 }
205 else
206 { /*checks if last_found is valid */
207 if ((data->last_found<data->lut_base_address)||(data->last_found>=data->shared_memory_base_address))
208 return TME_ERROR;
209 else
210 {
211 tmp=exec_fcn_mapper(SW_ULONG_AT(&((RECORD*)data->last_found)->exec_fcn,0));
212 if (tmp==NULL)
213 return TME_ERROR;
214 block=SW_ULONG_AT(&((RECORD*)data->last_found)->block,0)+mem_ex->buffer;
215 if ((block<data->shared_memory_base_address)||(block>=data->extra_segment_base_address))
216 return TME_ERROR;
217 }
218 }
219
220 if (offset>=mem_ex->size)
221 return TME_ERROR;
222
223 mem_data=mem_ex->buffer+offset;
224
225 return tmp(block,pkt_size,data,mem_ex,mem_data);
226 }
227
228 /*resets all the TME core*/
reset_tme(TME_CORE * tme)229 uint32 reset_tme(TME_CORE *tme)
230 {
231 if (tme==NULL)
232 return TME_ERROR;
233 ZERO_MEMORY(tme, sizeof(TME_CORE));
234 return TME_SUCCESS;
235 }
236
237 /* returns a register value of the active TME block */
238 /* FIXME last found in maniera elegante e veloce ?!?! */
get_tme_block_register(TME_DATA * data,MEM_TYPE * mem_ex,uint32 rgstr,uint32 * rval)239 uint32 get_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 *rval)
240 {
241 switch(rgstr)
242 {
243 case TME_LUT_ENTRIES:
244 *rval=data->lut_entries;
245 return TME_SUCCESS;
246 case TME_MAX_FILL_STATE:
247 *rval=data->max_fill_state;
248 return TME_SUCCESS;
249 case TME_REHASHING_VALUE:
250 *rval=data->rehashing_value;
251 return TME_SUCCESS;
252 case TME_KEY_LEN:
253 *rval=data->key_len;
254 return TME_SUCCESS;
255 case TME_SHARED_MEMORY_BLOCKS:
256 *rval=data->shared_memory_blocks;
257 return TME_SUCCESS;
258 case TME_FILLED_ENTRIES:
259 *rval=data->filled_entries;
260 return TME_SUCCESS;
261 case TME_BLOCK_SIZE:
262 *rval=data->block_size;
263 return TME_SUCCESS;
264 case TME_EXTRA_SEGMENT_SIZE:
265 *rval=data->extra_segment_size;
266 return TME_SUCCESS;
267 case TME_FILLED_BLOCKS:
268 *rval=data->filled_blocks;
269 return TME_SUCCESS;
270 case TME_DEFAULT_EXEC:
271 *rval=data->default_exec;
272 return TME_SUCCESS;
273 case TME_OUT_LUT_EXEC:
274 *rval=data->out_lut_exec;
275 return TME_SUCCESS;
276 case TME_SHARED_MEMORY_BASE_ADDRESS:
277 *rval=data->shared_memory_base_address-mem_ex->buffer;
278 return TME_SUCCESS;
279 case TME_LUT_BASE_ADDRESS:
280 *rval=data->lut_base_address-mem_ex->buffer;
281 return TME_SUCCESS;
282 case TME_EXTRA_SEGMENT_BASE_ADDRESS:
283 *rval=data->extra_segment_base_address-mem_ex->buffer;
284 return TME_SUCCESS;
285 case TME_LAST_FOUND_BLOCK:
286 if (data->last_found==NULL)
287 *rval=0;
288 else
289 *rval=data->last_found-mem_ex->buffer;
290 return TME_SUCCESS;
291
292 default:
293 return TME_ERROR;
294 }
295 }
296
297 /* sets a register value in the active block */
298 /* FIXME last found in maniera elegante e veloce ?!?! */
set_tme_block_register(TME_DATA * data,MEM_TYPE * mem_ex,uint32 rgstr,uint32 value,int32 init)299 uint32 set_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 value, int32 init)
300 { /* very very very dangerous!!!!!!!!!!! */
301 lut_fcn tmp;
302 switch(rgstr)
303 {
304 case TME_MAX_FILL_STATE:
305 data->max_fill_state=value;
306 return TME_SUCCESS;
307 case TME_REHASHING_VALUE:
308 data->rehashing_value=value;
309 return TME_SUCCESS;
310 case TME_FILLED_ENTRIES:
311 data->filled_entries=value;
312 return TME_SUCCESS;
313 case TME_FILLED_BLOCKS:
314 if (value<=data->shared_memory_blocks)
315 {
316 data->filled_blocks=value;
317 return TME_SUCCESS;
318 }
319 else
320 return TME_ERROR;
321 case TME_DEFAULT_EXEC:
322 data->default_exec=value;
323 return TME_SUCCESS;
324 case TME_OUT_LUT_EXEC:
325 data->out_lut_exec=value;
326 return TME_SUCCESS;
327 case TME_LOOKUP_CODE:
328 tmp=lut_fcn_mapper(value);
329 if (tmp==NULL)
330 return TME_ERROR;
331 else
332 data->lookup_code=tmp;
333 return TME_SUCCESS;
334 default:
335 break;
336 }
337
338 if (init)
339 switch (rgstr)
340 {
341
342 case TME_LUT_ENTRIES:
343 data->lut_entries=value;
344 return TME_SUCCESS;
345 case TME_KEY_LEN:
346 data->key_len=value;
347 return TME_SUCCESS;
348 case TME_SHARED_MEMORY_BLOCKS:
349 data->shared_memory_blocks=value;
350 return TME_SUCCESS;
351 case TME_BLOCK_SIZE:
352 data->block_size=value;
353 return TME_SUCCESS;
354 case TME_EXTRA_SEGMENT_SIZE:
355 data->extra_segment_size=value;
356 return TME_SUCCESS;
357 default:
358 return TME_ERROR;
359 }
360 else
361 return TME_ERROR;
362
363 }
364
365 /* chooses the TME block for read */
set_active_read_tme_block(TME_CORE * tme,uint32 block)366 uint32 set_active_read_tme_block(TME_CORE *tme, uint32 block)
367 {
368
369 if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block)))
370 return TME_ERROR;
371 tme->active_read=block;
372 return TME_SUCCESS;
373
374 }
375
376 /* chooses if the autodeletion must be used */
set_autodeletion(TME_DATA * data,uint32 value)377 uint32 set_autodeletion(TME_DATA *data, uint32 value)
378 {
379 if (value==0) /* no autodeletion */
380 data->enable_deletion=FALSE;
381 else
382 data->enable_deletion=TRUE;
383
384 return TME_SUCCESS;
385 }
386