3 * Politecnico di Torino. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the Politecnico
13 * di Torino, and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27 #include <net/tme/tme.h>
30 /* resizes extended memory */
31 uint32 init_extended_memory(uint32 size, MEM_TYPE *mem_ex)
35 if ((mem_ex==NULL)||(mem_ex->buffer==NULL)||(size==0))
36 return TME_ERROR; /* awfully never reached!!!! */
42 ALLOCATE_MEMORY(tmp,uint8,size);
44 return TME_ERROR; /* no memory */
52 /* activates a block of the TME */
53 uint32 set_active_tme_block(TME_CORE *tme, uint32 block)
56 if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block)))
64 /* simply inserts default values in a TME block */
65 /* it DOESN'T initialize the block in the core!! */
66 /* FIXME default values are defined at compile time, */
67 /* it will be useful to store them in the registry */
68 uint32 init_tme_block(TME_CORE *tme, uint32 block)
72 if (block>=MAX_TME_DATA_BLOCKS)
74 data=&(tme->block_data[block]);
77 ZERO_MEMORY(data,sizeof(TME_DATA));
80 data->lut_entries=TME_LUT_ENTRIES_DEFAULT;
82 data->shared_memory_blocks=TME_SHARED_MEMORY_BLOCKS_DEFAULT;
84 data->block_size=TME_BLOCK_SIZE_DEFAULT;
86 data->lookup_code=lut_fcn_mapper(TME_LOOKUP_CODE_DEFAULT);
88 data->rehashing_value=TME_REHASHING_VALUE_DEFAULT;
89 /* out lut function */
90 data->out_lut_exec=TME_OUT_LUT_EXEC_DEFAULT;
91 /* default function */
92 data->default_exec=TME_DEFAULT_EXEC_DEFAULT;
93 /* extra segment size */
94 data->extra_segment_size=TME_EXTRA_SEGMENT_SIZE_DEFAULT;
97 data->enable_deletion=FALSE;
98 data->last_read.tv_sec=0;
99 data->last_read.tv_usec=0;
103 /* it validates a TME block and */
104 /* (on OK) inserts the block in the core */
105 uint32 validate_tme_block(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 block, uint32 mem_ex_offset)
107 uint32 required_memory;
108 uint8 *base=mem_ex_offset+mem_ex->buffer;
111 /* FIXME soluzione un po' posticcia... */
112 if (mem_ex_offset==0)
115 if (block>=MAX_TME_DATA_BLOCKS)
117 data=&tme->block_data[block];
119 if (data->lut_entries==0)
122 if (data->key_len==0)
125 if (data->shared_memory_blocks==0)
128 if (data->block_size==0)
131 /* checks if the lookup function is valid */
132 if (data->lookup_code==NULL)
135 /* checks if the out lut exec function is valid */
136 if (exec_fcn_mapper(data->out_lut_exec)==NULL)
139 /* checks if the default exec function is valid */
140 if (exec_fcn_mapper(data->default_exec)==NULL)
143 /* let's calculate memory needed */
144 required_memory=data->lut_entries*sizeof(RECORD); /*LUT*/
145 required_memory+=data->block_size*data->shared_memory_blocks; /*shared segment*/
146 required_memory+=data->extra_segment_size; /*extra segment*/
148 if (required_memory>(mem_ex->size-mem_ex_offset))
149 return TME_ERROR; /*not enough memory*/
151 /* the TME block can be initialized */
152 ZERO_MEMORY(base,required_memory);
154 data->lut_base_address=base;
156 data->shared_memory_base_address=
157 data->lut_base_address+
158 data->lut_entries*sizeof(RECORD);
160 data->extra_segment_base_address=
161 data->shared_memory_base_address+
162 data->block_size*data->shared_memory_blocks;
163 data->filled_blocks=1;
164 VALIDATE(tme->validated_blocks,block);
170 /* I/F between the bpf machine and the callbacks, just some checks */
171 uint32 lookup_frontend(MEM_TYPE *mem_ex, TME_CORE *tme,uint32 mem_ex_offset, struct time_conv *time_ref)
173 if (tme->active==TME_NONE_ACTIVE)
176 return (tme->block_data[tme->active].lookup_code)(mem_ex_offset+mem_ex->buffer,&tme->block_data[tme->active],mem_ex, time_ref);
179 /* I/F between the bpf machine and the callbacks, just some checks */
180 uint32 execute_frontend(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 pkt_size, uint32 offset)
188 if (tme->active==TME_NONE_ACTIVE)
191 data=&tme->block_data[tme->active];
193 if (data->last_found==NULL)
195 tmp=exec_fcn_mapper(data->out_lut_exec);
196 block=data->shared_memory_base_address;
199 { /*checks if last_found is valid */
200 if ((data->last_found<data->lut_base_address)||(data->last_found>=data->shared_memory_base_address))
204 tmp=exec_fcn_mapper(SW_ULONG_AT(&((RECORD*)data->last_found)->exec_fcn,0));
207 block=SW_ULONG_AT(&((RECORD*)data->last_found)->block,0)+mem_ex->buffer;
208 if ((block<data->shared_memory_base_address)||(block>=data->extra_segment_base_address))
213 if (offset>=mem_ex->size)
216 mem_data=mem_ex->buffer+offset;
218 return tmp(block,pkt_size,data,mem_ex,mem_data);
221 /*resets all the TME core*/
222 uint32 reset_tme(TME_CORE *tme)
226 ZERO_MEMORY(tme, sizeof(TME_CORE));
230 /* returns a register value of the active TME block */
231 /* FIXME last found in maniera elegante e veloce ?!?! */
232 uint32 get_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 *rval)
236 case TME_LUT_ENTRIES:
237 *rval=data->lut_entries;
239 case TME_MAX_FILL_STATE:
240 *rval=data->max_fill_state;
242 case TME_REHASHING_VALUE:
243 *rval=data->rehashing_value;
248 case TME_SHARED_MEMORY_BLOCKS:
249 *rval=data->shared_memory_blocks;
251 case TME_FILLED_ENTRIES:
252 *rval=data->filled_entries;
255 *rval=data->block_size;
257 case TME_EXTRA_SEGMENT_SIZE:
258 *rval=data->extra_segment_size;
260 case TME_FILLED_BLOCKS:
261 *rval=data->filled_blocks;
263 case TME_DEFAULT_EXEC:
264 *rval=data->default_exec;
266 case TME_OUT_LUT_EXEC:
267 *rval=data->out_lut_exec;
269 case TME_SHARED_MEMORY_BASE_ADDRESS:
270 *rval=data->shared_memory_base_address-mem_ex->buffer;
272 case TME_LUT_BASE_ADDRESS:
273 *rval=data->lut_base_address-mem_ex->buffer;
275 case TME_EXTRA_SEGMENT_BASE_ADDRESS:
276 *rval=data->extra_segment_base_address-mem_ex->buffer;
278 case TME_LAST_FOUND_BLOCK:
279 if (data->last_found==NULL)
282 *rval=data->last_found-mem_ex->buffer;
290 /* sets a register value in the active block */
291 /* FIXME last found in maniera elegante e veloce ?!?! */
292 uint32 set_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 value, int32 init)
293 { /* very very very dangerous!!!!!!!!!!! */
297 case TME_MAX_FILL_STATE:
298 data->max_fill_state=value;
300 case TME_REHASHING_VALUE:
301 data->rehashing_value=value;
303 case TME_FILLED_ENTRIES:
304 data->filled_entries=value;
306 case TME_FILLED_BLOCKS:
307 if (value<=data->shared_memory_blocks)
309 data->filled_blocks=value;
314 case TME_DEFAULT_EXEC:
315 data->default_exec=value;
317 case TME_OUT_LUT_EXEC:
318 data->out_lut_exec=value;
320 case TME_LOOKUP_CODE:
321 tmp=lut_fcn_mapper(value);
325 data->lookup_code=tmp;
335 case TME_LUT_ENTRIES:
336 data->lut_entries=value;
341 case TME_SHARED_MEMORY_BLOCKS:
342 data->shared_memory_blocks=value;
345 data->block_size=value;
347 case TME_EXTRA_SEGMENT_SIZE:
348 data->extra_segment_size=value;
358 /* chooses the TME block for read */
359 uint32 set_active_read_tme_block(TME_CORE *tme, uint32 block)
362 if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block)))
364 tme->active_read=block;
369 /* chooses if the autodeletion must be used */
370 uint32 set_autodeletion(TME_DATA *data, uint32 value)
372 if (value==0) /* no autodeletion */
373 data->enable_deletion=FALSE;
375 data->enable_deletion=TRUE;