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