1 /**********************************************************\r
2 * file: netcp_cfg.c\r
3 * purpose: netcp configurations routines\r
4 **************************************************************\r
5 * FILE: netcp_cfg.c\r
6 * \r
7 * DESCRIPTION: netcp configuration main source file for user space transport\r
8 * library\r
9 * \r
10 * REVISION HISTORY: rev 0.0.1 \r
11 *\r
12 * Copyright (c) Texas Instruments Incorporated 2010-2011\r
13 * \r
14 * Redistribution and use in source and binary forms, with or without \r
15 * modification, are permitted provided that the following conditions \r
16 * are met:\r
17 *\r
18 * Redistributions of source code must retain the above copyright \r
19 * notice, this list of conditions and the following disclaimer.\r
20 *\r
21 * Redistributions in binary form must reproduce the above copyright\r
22 * notice, this list of conditions and the following disclaimer in the \r
23 * documentation and/or other materials provided with the \r
24 * distribution.\r
25 *\r
26 * Neither the name of Texas Instruments Incorporated nor the names of\r
27 * its contributors may be used to endorse or promote products derived\r
28 * from this software without specific prior written permission.\r
29 *\r
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
41 \r
42 ******************************************************/\r
43 #include <stdio.h>\r
44 #include <stdlib.h>\r
45 #include <unistd.h>\r
46 #include <string.h>\r
47 #include "netapi.h"\r
48 #include "netcp_cfg.h"\r
49 #include "netapi_loc.h"\r
50 \r
51 /******************************************************************\r
52 ********************Utility*************************************\r
53 *******************************************************************/\r
54 \r
55 \r
56 //get a free transaction id\r
57 static NetapiNwalTransInfo_t * netapi_GetFreeTransInfo(NETAPI_GLOBAL_T *p_global, nwal_TransID_t *pTransId)\r
58 {\r
59 uint16_t count=0;\r
60 \r
61 count=0;\r
62 while(count < TUNE_NETAPI_MAX_NUM_TRANS)\r
63 {\r
64 if((p_global->nwal_context.transInfos[count].inUse) != nwal_TRUE)\r
65 {\r
66 p_global->nwal_context.transInfos[count].inUse = nwal_TRUE;\r
67 *pTransId = count;\r
68 return(&p_global->nwal_context.transInfos[count]);\r
69 }\r
70 count++;\r
71 }\r
72 \r
73 /* trouble. need to wait for one to free up*/\r
74 /* to do: handle this by forcing a poll of cntrl queue*/\r
75 printf(">netcp_cfg: trying to get free transaction slot but all full!!\n");\r
76 return NULL;\r
77 \r
78 }\r
79 \r
80 //internal: find a free slot for IP rule in interface\r
81 static int netcp_cfgp_find_ip_slot(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
82 int iface_no)\r
83 {\r
84 int i;\r
85 if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
86 {\r
87 return -1;\r
88 }\r
89 if (!p->interfaces[iface_no].in_use) return -1;\r
90 \r
91 //find a free entry\r
92 for(i=0;i<TUNE_NETAPI_MAX_IP_PER_INTERFACE;i++)\r
93 {\r
94 if (!p->interfaces[iface_no].ips[i].in_use)\r
95 {\r
96 p->interfaces[iface_no].ips[i].in_use = 2; //pending\r
97 return i;\r
98 }\r
99 }\r
100 return -1;\r
101 }\r
102 \r
103 //internal: find a free slot for classifier rule\r
104 static int netcp_cfgp_find_class_slot( NETAPI_NWAL_GLOBAL_CONTEXT_T *p)\r
105 {\r
106 int i;\r
107 //find a free entry\r
108 for(i=0;i<TUNE_NETAPI_MAX_CLASSIFIERS;i++)\r
109 {\r
110 if (!p->classi[i].in_use)\r
111 {\r
112 p->classi[i].in_use = 2; //pending\r
113 return i;\r
114 }\r
115 }\r
116 return -1; \r
117 }\r
118 \r
119 //internal: insert an IP address into iface\r
120 static void netcp_cfgp_insert_ip(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
121 nwal_IpType ipType,\r
122 nwalIpAddr_t *ip_addr, \r
123 nwalIpOpt_t *ip_qualifiers, \r
124 int iface_no,\r
125 int ip_slot, //we 'reserved it already'\r
126 void * handle)\r
127 {\r
128 p->interfaces[iface_no].ips[ip_slot].in_use=1;\r
129 memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_addr, ip_addr, sizeof(nwalIpAddr_t));\r
130 if(ip_qualifiers)\r
131 memcpy(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, ip_qualifiers, sizeof(nwalIpOpt_t));\r
132 else\r
133 memset(&p->interfaces[iface_no].ips[ip_slot].ip_qualifiers, 0, sizeof(nwalIpOpt_t));\r
134 p->interfaces[iface_no].ips[ip_slot].ip_type = ipType;\r
135 p->interfaces[iface_no].ips[ip_slot].nwal_handle = handle;\r
136 return;\r
137 }\r
138 \r
139 \r
140 //internal: insert interface info into global context\r
141 static void netcp_cfgp_insert_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p, unsigned char * p_mac, \r
142 int iface_no, int state, NETCP_CFG_VLAN_T vlan, void * handle)\r
143 {\r
144 if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
145 {\r
146 memset(&p->interfaces[iface_no],0,sizeof(NETCP_INTERFACE_T));\r
147 p->interfaces[iface_no].in_use = 1;\r
148 memcpy(&p->interfaces[iface_no].mac[0], p_mac,6);\r
149 p->interfaces[iface_no].state = state;\r
150 //todo p->interfaces[iface_no].vlan = vlan;\r
151 p->interfaces[iface_no].nwal_handle = handle; //save handle assoicated with this rule\r
152 }\r
153 else printf(">netcp_cfg insert interface # out of range %d\n",iface_no);\r
154 \r
155 }\r
156 //internal: clear inteface entry\r
157 static void netcp_cfgp_delete_mac(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no) \r
158 {\r
159 if ((iface_no >=0 ) && (iface_no < TUNE_NETAPI_MAX_INTERFACES))\r
160 {\r
161 p->interfaces[iface_no].in_use = 0;\r
162 }\r
163 }\r
164 //internal: free IP slot associated with ip address \r
165 static void netcp_cfgp_delete_ip(\r
166 NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
167 int iface_no,\r
168 int ip_slot )\r
169 {\r
170 if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
171 {\r
172 return ;\r
173 }\r
174 if (!p->interfaces[iface_no].in_use) return ;\r
175 if ((ip_slot <0)||(ip_slot>TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return ;\r
176 p->interfaces[iface_no].ips[ip_slot].in_use=0;\r
177 return;\r
178 }\r
179 \r
180 \r
181 //internal: get IP handle associated with ip address \r
182 static void *netcp_cfgp_get_ip_handle(\r
183 NETAPI_NWAL_GLOBAL_CONTEXT_T *p, \r
184 int iface_no,\r
185 int ip_slot )\r
186 {\r
187 if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
188 {\r
189 return NULL;\r
190 }\r
191 if (!p->interfaces[iface_no].in_use) return NULL;\r
192 if ((ip_slot <0)||(ip_slot>=TUNE_NETAPI_MAX_IP_PER_INTERFACE)) return NULL;\r
193 if (!p->interfaces[iface_no].ips[ip_slot].in_use) return NULL;\r
194 return (void *) p->interfaces[iface_no].ips[ip_slot].nwal_handle;\r
195 }\r
196 \r
197 //internal: get handle associated with interface\r
198 static void* netcp_cfgp_get_mac_handle(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,int iface_no)\r
199 {\r
200 if ((iface_no <0 ) || (iface_no >= TUNE_NETAPI_MAX_INTERFACES))\r
201 {\r
202 return NULL;\r
203 }\r
204 else if ( p->interfaces[iface_no].in_use)\r
205 {\r
206 return (void *) p->interfaces[iface_no].nwal_handle;\r
207 }\r
208 //no valid entry in slot\r
209 return NULL;\r
210 }\r
211 \r
212 //internal: delete a classifer from list \r
213 static void netcp_cfgp_delete_class(\r
214 NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
215 int class_slot )\r
216 {\r
217 if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS))\r
218 {\r
219 return ;\r
220 }\r
221 p->classi[class_slot].in_use=0;\r
222 return;\r
223 }\r
224 \r
225 //internal: insert a classifier into list \r
226 static void netcp_cfgp_insert_class(NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
227 int class_slot, //we 'reserved it already'\r
228 int class_type,\r
229 void * L2_handle,\r
230 void * L3_handle,\r
231 void * L4_handle)\r
232 {\r
233 p->classi[class_slot].in_use=1;\r
234 p->classi[class_slot].nwal_L2_handle = L2_handle;\r
235 p->classi[class_slot].nwal_L3_handle = L3_handle;\r
236 p->classi[class_slot].nwal_L4_handle = L4_handle;\r
237 p->classi[class_slot].class_type = class_type;\r
238 return;\r
239 }\r
240 \r
241 //internal: return nwal_handle for class\r
242 static void *netcp_cfgp_get_class_handle( NETAPI_NWAL_GLOBAL_CONTEXT_T *p,\r
243 int class_slot)\r
244 {\r
245 if ((class_slot <0 ) || (class_slot >= TUNE_NETAPI_MAX_CLASSIFIERS)) return NULL;\r
246 if (!p->classi[class_slot].in_use) return NULL;\r
247 return p->classi[class_slot].nwal_L4_handle;\r
248 }\r
249 \r
250 /***********************************************************************************/\r
251 /****************************************API****************************************/\r
252 /***********************************************************************************/\r
253 \r
254 \r
255 /*****************************************************************\r
256 * Queury Stats\r
257 ****************************************************************/\r
258 void netcp_cfgReqStats(NETAPI_T h, NETCP_CFG_STATS_CB cb, int doClear, int *err) \r
259 {\r
260 nwal_RetValue ret;\r
261 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
262 NetapiNwalTransInfo_t *pTransInfo;\r
263 nwal_TransID_t transId;\r
264 if ((!n) || (!cb)) {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
265 *err =0;\r
266 \r
267 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &transId);\r
268 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;}\r
269 pTransInfo->transType = NETAPI_NWAL_HANDLE_STAT_REQUEST;\r
270 pTransInfo->netapi_handle = h;\r
271 n->nwal_local.stats_cb = cb;\r
272 ret = nwal_getPAStats( ((NETAPI_GLOBAL_T *) n->global)->nwal_context.nwalInstHandle,\r
273 transId,\r
274 NULL,\r
275 doClear);\r
276 if(ret != nwal_OK)\r
277 {\r
278 pTransInfo->inUse = nwal_FALSE;\r
279 *err = NETAPI_ERR_BUSY; //no resources??\r
280 printf("> netcp_cfg reqStats failed, err=%d\n",ret);\r
281 }\r
282 \r
283 }\r
284 /*****************************************************************\r
285 * CREATE A MAC INTERFACE\r
286 ****************************************************************/\r
287 NETCP_CFG_MACIF_T netcp_cfgCreateMacInterface(\r
288 NETAPI_T h,\r
289 uint8_t *p_mac,\r
290 int iface_no, \r
291 int switch_port, \r
292 NETCP_CFG_ROUTE_HANDLE_T route,\r
293 NETCP_CFG_VLAN_T vlan, //future\r
294 int state, //0=down, 1=up //ignored\r
295 int * err\r
296 )\r
297 {\r
298 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
299 nwalMacParam_t MacInfo= {\r
300 0, /* validParams */\r
301 0, /* ifNum */\r
302 0, /* vlanId */\r
303 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Local mac */\r
304 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */\r
305 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */\r
306 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */\r
307 QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */\r
308 };\r
309 \r
310 nwal_RetValue retValue;\r
311 NetapiNwalTransInfo_t *pTransInfo;\r
312 nwal_TransID_t trans_id;\r
313 \r
314 if ((!n) || (!p_mac)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
315 *err =0;\r
316 \r
317 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
318 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return -1;}\r
319 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
320 pTransInfo->netapi_handle = h; \r
321 \r
322 /* set up MacInfo */\r
323 memcpy(&MacInfo.macAddr,p_mac,6); \r
324 /* todo: vlan */\r
325 MacInfo.ifNum = switch_port; /* todo: check for 0/1 relative*/\r
326 \r
327 #if 0 //todo\r
328 if (route != NULL)\r
329 {\r
330 MacInfo.appRxPktFlowId = ((NETCP_CFG_FLOW_T *)(route.flow))->flowid;\r
331 MacInfo.appRxPktQueue = PKTIO_GET_Q(route->p_dest_q);\r
332 //handle action ??\r
333 }\r
334 #endif\r
335 pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
336 retValue = nwal_setMacIface( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
337 trans_id,\r
338 (nwal_AppId) (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no),\r
339 &MacInfo,\r
340 &pTransInfo->handle);\r
341 if(retValue != nwal_OK)\r
342 {\r
343 *err = NETAPI_ERR_NWAL_ERR0;\r
344 printf (">netcp cfg - ERROR: nwal_setMacIface returned Error Code %d\n",\r
345 retValue);\r
346 pTransInfo->inUse = nwal_FALSE;\r
347 return -1;\r
348 }\r
349 //pTransInfo->inUse = nwal_FALSE;\r
350 \r
351 //wait here until its done since scheduler isn't running yet most likely..\r
352 // todo: make this handled by scheduler poll later ??\r
353 if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
354 {\r
355 n->nwal_local.numPendingCfg++;\r
356 while ((volatile) n->nwal_local.numPendingCfg)\r
357 {\r
358 // if response is there, then this poll squirts out in the CTl poll callback, \r
359 // which handles the rest (including decrmenting #pending!!\r
360 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
361 }\r
362 }\r
363 printf (">netcp cfg: MAC i/f %d added\n", iface_no);\r
364 netcp_cfgp_insert_mac(&netapi_get_global()->nwal_context, \r
365 p_mac, iface_no, state,vlan,\r
366 (void *) pTransInfo->handle);\r
367 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;\r
368 pTransInfo->inUse = nwal_FALSE;\r
369 return (NETAPI_NETCP_MATCH_GENERIC_MAC | iface_no);\r
370 }\r
371 \r
372 \r
373 /*****************************************************************/\r
374 /***************Delete a mac interface****************************/\r
375 /*****************************************************************/\r
376 void netcp_cfgDelMac(NETAPI_T h,int iface_no, int *err)\r
377 {\r
378 nwal_RetValue ret;\r
379 NetapiNwalTransInfo_t *pTransInfo;\r
380 nwal_TransID_t trans_id;\r
381 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
382 void * ifHandle;\r
383 \r
384 //get the nwal handle assoicated with this iface\r
385 ifHandle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no );\r
386 if(!ifHandle) \r
387 {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
388 *err =0;\r
389 \r
390 //get a transaction id\r
391 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
392 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;}\r
393 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_MAC;\r
394 pTransInfo->netapi_handle = h;\r
395 //issue request\r
396 ret = nwal_delMacIface(\r
397 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
398 trans_id,\r
399 ifHandle);\r
400 if(ret != nwal_OK)\r
401 {\r
402 *err = NETAPI_ERR_NWAL_ERR0;\r
403 printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
404 ret);\r
405 pTransInfo->inUse = nwal_FALSE;\r
406 return ;\r
407 }\r
408 //wait here until its done since scheduler isn't running yet most likely..\r
409 // todo: make this handled by scheduler poll later ??\r
410 if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
411 {\r
412 n->nwal_local.numPendingCfg++;\r
413 while ((volatile) n->nwal_local.numPendingCfg)\r
414 {\r
415 // if response is there, then this poll squirts out in the CTl poll callback, \r
416 // which handles the rest (including decrmenting #pending!!\r
417 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
418 }\r
419 }\r
420 printf (">netcp cfg: MAC i/f %d deleted\n",iface_no);\r
421 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;\r
422 pTransInfo->inUse = nwal_FALSE;\r
423 //zap the entry\r
424 netcp_cfgp_delete_mac(&netapi_get_global()->nwal_context, iface_no);\r
425 return ;\r
426 }\r
427 \r
428 \r
429 /*****************************************************************/\r
430 /***************Add IP to MAC interface (internal)****************/\r
431 /*****************************************************************/\r
432 static NETCP_CFG_IP_T netcp_cfgAddIpInternal(\r
433 NETAPI_T h,\r
434 int iface_no,\r
435 nwal_IpType ipType,\r
436 nwalIpAddr_t * ip_addr,\r
437 nwalIpOpt_t * ip_qualifiers,\r
438 NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default\r
439 int * err,\r
440 int flag) //TRUE: add IP to iface. False: add IP as part of classifier\r
441 {\r
442 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
443 void * n_handle;\r
444 nwalIpParam_t nwalIpParam= {\r
445 pa_IPV4, /* IP Type */\r
446 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Dest IP */\r
447 { 0x0,0,0,0},/* IP Options */\r
448 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */\r
449 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */\r
450 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */\r
451 QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */\r
452 };\r
453 nwal_RetValue retValue;\r
454 NetapiNwalTransInfo_t *pTransInfo;\r
455 nwal_TransID_t trans_id;\r
456 int ip_slot=-1;\r
457 NETCP_CFG_IP_T ip_rule_id;\r
458 NETCP_CFG_IP_T temp;\r
459 \r
460 //verify that iface has been configurred \r
461 if ((iface_no<0) || (iface_no>= TUNE_NETAPI_MAX_INTERFACES)) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
462 \r
463 if(netapi_get_global()->nwal_context.interfaces[iface_no].in_use)\r
464 {\r
465 n_handle = netapi_get_global()->nwal_context.interfaces[iface_no].nwal_handle;\r
466 }\r
467 else\r
468 {\r
469 *err = NETAPI_ERR_BAD_INPUT;\r
470 return -1;\r
471 }\r
472 \r
473 if (flag) //if adding IP to MAC then reserve a slot to save info\r
474 {\r
475 //find free slot for IP & reserve\r
476 ip_slot= netcp_cfgp_find_ip_slot(&netapi_get_global()->nwal_context, \r
477 iface_no);\r
478 if (ip_slot <0) \r
479 {\r
480 *err= NETAPI_ERR_NOMEM; //no room \r
481 return -1;\r
482 }\r
483 }\r
484 \r
485 //get a transaction object for config action\r
486 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
487 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return -1;}\r
488 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
489 pTransInfo->netapi_handle = h;\r
490 \r
491 //build nwalIpParam\r
492 memcpy(&nwalIpParam.locIpAddr,ip_addr, sizeof(nwalIpAddr_t));\r
493 nwalIpParam.ipType=ipType;\r
494 if(route)\r
495 {\r
496 //todo: support app defined routes\r
497 } \r
498 else{} //use nwal defaults\r
499 if (ip_qualifiers)\r
500 memcpy(&nwalIpParam.ipOpt,ip_qualifiers, sizeof(nwalIpOpt_t)); \r
501 else\r
502 memset(&nwalIpParam.ipOpt,0, sizeof(nwalIpOpt_t));\r
503 \r
504 //build the rule id that will be returned when a packet matches \r
505 if (flag)\r
506 ip_rule_id = NETAPI_NETCP_MATCH_GENERIC_IP | iface_no | ((ip_slot&&0xff)<<8);\r
507 else\r
508 ip_rule_id = (NETAPI_NETCP_MATCH_CLASS_L3 | iface_no);\r
509 \r
510 //perform config action\r
511 pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;\r
512 retValue = nwal_setIPAddr( netapi_get_global()->nwal_context.nwalInstHandle,\r
513 trans_id,\r
514 (nwal_AppId) (ip_rule_id),\r
515 n_handle,\r
516 &nwalIpParam,\r
517 &pTransInfo->handle);\r
518 \r
519 if(retValue != nwal_OK)\r
520 {\r
521 *err = NETAPI_ERR_NWAL_ERR0;\r
522 printf (">netcp cfg: nwal_setIP returned Error Code %d\n",\r
523 retValue);\r
524 pTransInfo->inUse = nwal_FALSE;\r
525 //zap the entry\r
526 if (flag)\r
527 {\r
528 netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context,\r
529 iface_no,\r
530 ip_slot);\r
531 }\r
532 return -1;\r
533 }\r
534 //wait here until its done since scheduler isn't running yet most likely..\r
535 // todo: make this handled by scheduler poll later ??\r
536 if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
537 {\r
538 n->nwal_local.numPendingCfg++;\r
539 while ((volatile) n->nwal_local.numPendingCfg)\r
540 {\r
541 // if response is there, then this poll squirts out in the CTl poll callback, \r
542 // which handles the rest (including decrmenting #pending!!\r
543 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
544 }\r
545 }\r
546 if (flag)\r
547 {\r
548 printf (">netcp cfg: IP added to interface %d (slot%d)\n", iface_no, ip_slot);\r
549 netcp_cfgp_insert_ip(&netapi_get_global()->nwal_context, ipType, \r
550 ip_addr, ip_qualifiers, iface_no, ip_slot,\r
551 pTransInfo->handle);\r
552 }\r
553 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;\r
554 temp = (NETCP_CFG_IP_T) pTransInfo->handle;\r
555 pTransInfo->inUse = nwal_FALSE;\r
556 return (flag ? ip_rule_id: temp);\r
557 }\r
558 /*****************************************************************/\r
559 /***************Add IP to MAC interface **************************/\r
560 /*****************************************************************/\r
561 NETCP_CFG_IP_T netcp_cfgAddIp(\r
562 NETAPI_T h,\r
563 int iface_no,\r
564 nwal_IpType ipType,\r
565 nwalIpAddr_t * ip_addr,\r
566 nwalIpOpt_t * ip_qualifiers,\r
567 NETCP_CFG_ROUTE_HANDLE_T route, //NULL for default\r
568 int * err\r
569 )\r
570 {\r
571 return netcp_cfgAddIpInternal(\r
572 h, iface_no, ipType, ip_addr, ip_qualifiers, route, err, \r
573 1);\r
574 }\r
575 \r
576 /*****************************************************************/\r
577 /***************Delete an attached IP*****************************/\r
578 /*****************************************************************/\r
579 void netcp_cfgDelIp(NETAPI_T h, int iface_no, nwal_IpType ipType,\r
580 nwalIpAddr_t * ip_addr,\r
581 nwalIpOpt_t * ip_qualifiers, \r
582 NETCP_CFG_IP_T ip_rule_id,\r
583 int *err)\r
584 {\r
585 nwal_RetValue ret;\r
586 NetapiNwalTransInfo_t *pTransInfo;\r
587 nwal_TransID_t trans_id;\r
588 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
589 void * ifHandle;\r
590 int ip_slot = (ip_rule_id>>8)&0xff;\r
591 \r
592 //get the nwal handle assoicated with this ip \r
593 ifHandle = netcp_cfgp_get_ip_handle(\r
594 &netapi_get_global()->nwal_context, iface_no,\r
595 ip_slot );\r
596 if(!ifHandle)\r
597 {*err = NETAPI_ERR_BAD_INPUT; return ;}\r
598 *err =0;\r
599 \r
600 //get a transaction id\r
601 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
602 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return ;}\r
603 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
604 pTransInfo->netapi_handle = h;\r
605 //issue request\r
606 ret = nwal_delIPAddr(\r
607 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
608 trans_id,\r
609 ifHandle);\r
610 if(ret != nwal_OK)\r
611 {\r
612 *err = NETAPI_ERR_NWAL_ERR0;\r
613 printf (">netcp cfg - ERROR: nwal_delMacIface returned Error Code %d\n",\r
614 ret);\r
615 pTransInfo->inUse = nwal_FALSE;\r
616 return ;\r
617 }\r
618 //wait here until its done since scheduler isn't running yet most likely..\r
619 // todo: make this handled by scheduler poll later ??\r
620 if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
621 {\r
622 n->nwal_local.numPendingCfg++;\r
623 while ((volatile) n->nwal_local.numPendingCfg)\r
624 {\r
625 // if response is there, then this poll squirts out in the CTl poll callback, \r
626 // which handles the rest (including decrmenting #pending!!\r
627 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
628 }\r
629 }\r
630 printf (">netcp cfg: IP i/f deleted\n");\r
631 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;\r
632 pTransInfo->inUse = nwal_FALSE;\r
633 //zap the entry\r
634 netcp_cfgp_delete_ip(&netapi_get_global()->nwal_context, \r
635 iface_no,\r
636 ip_slot);\r
637 return ;\r
638 }\r
639 \r
640 /**\r
641 * @def netcp_cfgAddClass\r
642 * @brief add a classifier rule into NETCP\r
643 **/\r
644 NETCP_CFG_CLASS_T netcp_cfgAddClass(NETAPI_T h,\r
645 NETCP_CFG_CLASSIFIER_T *p_class,\r
646 NETCP_CFG_ROUTE_HANDLE_T p_route,\r
647 int action, int * err)\r
648 {\r
649 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
650 void * l3_handle=NULL; //ip handle\r
651 nwal_RetValue retValue;\r
652 NetapiNwalTransInfo_t *pTransInfo;\r
653 nwal_TransID_t trans_id;\r
654 int class_slot=-1;\r
655 int iface_no;\r
656 int ip_slot=-1;\r
657 NETCP_CFG_CLASS_T classHandle; //returned by us\r
658 nwal_appProtoType_t proto;\r
659 nwalLocConnCfg_t tempCfg={\r
660 0, //nwal_handle: to be filled in\r
661 {0}, // l4 ports: to be filled in\r
662 0, //core id (NA)\r
663 0, //action\r
664 CPPI_PARAM_NOT_SPECIFIED, //flow id\r
665 QMSS_PARAM_NOT_SPECIFIED, //dest queue\r
666 };\r
667 \r
668 if(!p_class) { *err=NETAPI_ERR_BAD_INPUT; return -1;}\r
669 switch(p_class->classType)\r
670 {\r
671 default:\r
672 printf(">netcp_cfg : classifier type %d not supported\n",p_class->classType);\r
673 break;\r
674 case(NETCP_CFG_CLASS_TYPE_L3_L4):\r
675 case(NETCP_CFG_CLASS_TYPE_L4):\r
676 //assume just type l4 only (L2, L3 defined by iface, l3 id )\r
677 iface_no = p_class->u.c_l4.iface;\r
678 if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
679 { \r
680 ip_slot = (p_class->u.c_l4.ip>>8)&0xff;\r
681 }\r
682 \r
683 //verify that iface has been configured \r
684 if(!netapi_get_global()->nwal_context.interfaces[iface_no].in_use)\r
685 {\r
686 *err = NETAPI_ERR_BAD_INPUT;\r
687 return -1;\r
688 }\r
689 \r
690 if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
691 {\r
692 //verify that ip has been configured and get its handle\r
693 l3_handle = netcp_cfgp_get_ip_handle(\r
694 &netapi_get_global()->nwal_context, iface_no,\r
695 ip_slot );\r
696 }\r
697 else\r
698 {\r
699 nwalIpParam_t tempParam={\r
700 pa_IPV4, /* IP Type */\r
701 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Dest IP */\r
702 { 0x0,0,0,0},/* IP Options */\r
703 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */\r
704 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */\r
705 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */\r
706 QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */\r
707 };\r
708 //build nwalIpParam\r
709 memcpy(&tempParam.locIpAddr,p_class->u.c_l3_l4.ip_addr, sizeof(nwalIpAddr_t));\r
710 tempParam.ipType=p_class->u.c_l3_l4.ipType;\r
711 //use nwal defauls for route\r
712 if (p_class->u.c_l3_l4.ip_qualifiers)\r
713 memcpy(&tempParam.ipOpt,p_class->u.c_l3_l4.ip_qualifiers, sizeof(nwalIpOpt_t));\r
714 else\r
715 memset(&tempParam.ipOpt,0, sizeof(nwalIpOpt_t));\r
716 \r
717 \r
718 //find if we have a matching L3 handle for IP classifier; if not create it\r
719 retValue = nwal_getIPAddr (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
720 &tempParam,\r
721 netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context, iface_no ),\r
722 &l3_handle); \r
723 if (retValue != nwal_TRUE) \r
724 {\r
725 int ret;\r
726 //**NEW IP RULE \r
727 //need to attach this IP RULE to the MAC\r
728 l3_handle= (void *) netcp_cfgAddIpInternal(\r
729 h, iface_no, \r
730 p_class->u.c_l3_l4.ipType,\r
731 p_class->u.c_l3_l4.ip_addr,\r
732 p_class->u.c_l3_l4.ip_qualifiers,\r
733 p_class->u.c_l3_l4.p_fail_route,\r
734 &ret,\r
735 FALSE);\r
736 if(!ret)\r
737 {\r
738 l3_handle=NULL;\r
739 }\r
740 }\r
741 } \r
742 if(!l3_handle)\r
743 {*err = NETAPI_ERR_BAD_INPUT; return -1 ;}\r
744 \r
745 \r
746 //find free slot for CLASS & reserve\r
747 class_slot= netcp_cfgp_find_class_slot(&netapi_get_global()->nwal_context);\r
748 if(class_slot<0) {*err = NETAPI_ERR_NOMEM; return -1;}\r
749 classHandle = NETAPI_NETCP_MATCH_CLASS | (class_slot<<8) | (iface_no&0xff);\r
750 //build request from template\r
751 tempCfg.inHandle=l3_handle;\r
752 if (p_class->classType== NETCP_CFG_CLASS_TYPE_L4)\r
753 { \r
754 memcpy(&tempCfg.appProto,&p_class->u.c_l4.appProto,sizeof(nwalAppProto_t));\r
755 proto = p_class->u.c_l4.proto;\r
756 }\r
757 else\r
758 {\r
759 memcpy(&tempCfg.appProto,&p_class->u.c_l3_l4.appProto,sizeof(nwalAppProto_t));\r
760 proto = p_class->u.c_l3_l4.proto;\r
761 }\r
762 \r
763 tempCfg.matchAction = (action==NETCP_CFG_ACTION_TO_SW) ? NWAL_MATCH_ACTION_HOST : NWAL_MATCH_ACTION_DISCARD;\r
764 //todo: flowid and route \r
765 //get a transaction id\r
766 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
767 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return -1 ;}\r
768 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP; /* todo: fix this to TRANS_L4*/\r
769 pTransInfo->netapi_handle = h;\r
770 //issue request\r
771 retValue = nwal_addConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
772 trans_id,\r
773 (nwal_AppId) classHandle,\r
774 proto,\r
775 &tempCfg,\r
776 NULL,\r
777 &pTransInfo->handle);\r
778 if(retValue != nwal_OK)\r
779 {\r
780 *err = NETAPI_ERR_NWAL_ERR0;\r
781 printf (">netcp cfg - ERROR: nwal_addConn returned Error Code %d\n",\r
782 retValue);\r
783 pTransInfo->inUse = nwal_FALSE;\r
784 netcp_cfgp_delete_class(&netapi_get_global()->nwal_context, class_slot);\r
785 return -1;\r
786 }\r
787 //wait here until its done since scheduler isn't running yet most likely..\r
788 // todo: make this handled by scheduler poll later ??\r
789 if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
790 {\r
791 n->nwal_local.numPendingCfg++;\r
792 while ((volatile) n->nwal_local.numPendingCfg)\r
793 {\r
794 // if response is there, then this poll squirts out in the CTl poll callback, \r
795 // which handles the rest (including decrmenting #pending!!\r
796 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
797 }\r
798 }\r
799 printf (">netcp cfg: L4 Classifer added to interface %d ip %d (slot%d)\n", iface_no, ip_slot, class_slot);\r
800 netcp_cfgp_insert_class(&netapi_get_global()->nwal_context, \r
801 class_slot,\r
802 p_class->classType, \r
803 NULL, //L2 we have\r
804 (p_class->classType== NETCP_CFG_CLASS_TYPE_L3_L4? l3_handle : NULL),\r
805 pTransInfo->handle);\r
806 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;\r
807 return classHandle;\r
808 } //end switch\r
809 return -1;\r
810 }\r
811 \r
812 //delete classifier\r
813 void netcp_cfgDelClass(NETAPI_T h,\r
814 NETCP_CFG_CLASS_T classId,\r
815 int *err)\r
816 {\r
817 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;\r
818 void * class_handle; //class handle\r
819 nwal_RetValue retValue;\r
820 NetapiNwalTransInfo_t *pTransInfo;\r
821 nwal_TransID_t trans_id;\r
822 int class_slot=-1;\r
823 //int iface;\r
824 //int ip_slot;\r
825 \r
826 class_slot = (classId>>8)&0xffff;\r
827 class_handle=netcp_cfgp_get_class_handle(\r
828 &netapi_get_global()->nwal_context,\r
829 class_slot );\r
830 if(!class_handle) {*err = NETAPI_ERR_BAD_INPUT; return -1;}\r
831 netcp_cfgp_delete_class(\r
832 &netapi_get_global()->nwal_context,\r
833 class_slot );\r
834 //get a transaction id\r
835 pTransInfo = netapi_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);\r
836 if (!pTransInfo) { *err = NETAPI_ERR_BUSY; return -1 ;}\r
837 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_IP;\r
838 pTransInfo->netapi_handle = h;\r
839 //issue request\r
840 retValue = nwal_delConn(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,\r
841 trans_id,\r
842 class_handle);\r
843 if(retValue != nwal_OK)\r
844 {\r
845 *err = NETAPI_ERR_NWAL_ERR0;\r
846 printf (">netcp cfg - ERROR: nwal_delConn returned Error Code %d\n",\r
847 retValue);\r
848 pTransInfo->inUse = nwal_FALSE;\r
849 return -1;\r
850 }\r
851 //wait here until its done since scheduler isn't running yet most likely..\r
852 // todo: make this handled by scheduler poll later ??\r
853 if(trans_id != NWAL_TRANSID_SPIN_WAIT)\r
854 {\r
855 n->nwal_local.numPendingCfg++;\r
856 while ((volatile) n->nwal_local.numPendingCfg)\r
857 {\r
858 // if response is there, then this poll squirts out in the CTl poll callback, \r
859 // which handles the rest (including decrmenting #pending!!\r
860 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);\r
861 }\r
862 }\r
863 printf (">netcp cfg: Classifer deleted\n");\r
864 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;\r
865 pTransInfo->inUse = nwal_FALSE;\r
866 return ;\r
867 }\r
868 \r
869 \r
870 /*************************************************************************/\r
871 /*********************************INTERNAL*******************************/\r
872 /************************************************************************/\r
873 \r
874 /***************************************************************\r
875 ********************METCP CMD Reply Callback******************\r
876 ***************************************************************/\r
877 void netapi_NWALCmdCallBack (nwal_AppId appHandle,\r
878 uint16_t trans_id,\r
879 nwal_RetValue ret)\r
880 {\r
881 NetapiNwalTransInfo_t * p_trans;\r
882 NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
883 \r
884 if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
885 {\r
886 netapi_get_global()->nwal_context.numBogusTransIds++;\r
887 return;\r
888 }\r
889 \r
890 p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
891 p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
892 \r
893 if(ret != nwal_OK)\r
894 {\r
895 printf (">netcp cfg : NWALCmdCallBack returned Error Code %d\n",\r
896 ret);\r
897 //todo: atomic inc\r
898 netapi_get_global()->nwal_context.numCmdFail++;\r
899 }\r
900 else\r
901 {\r
902 //todo: atomic inc\r
903 netapi_get_global()->nwal_context.numCmdPass++;\r
904 switch(p_trans->transType)\r
905 {\r
906 case NETAPI_NWAL_HANDLE_TRANS_MAC:\r
907 {\r
908 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
909 {\r
910 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
911 }\r
912 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
913 {\r
914 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
915 }\r
916 break;\r
917 }\r
918 case NETAPI_NWAL_HANDLE_TRANS_IP:\r
919 {\r
920 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
921 {\r
922 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
923 }\r
924 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
925 {\r
926 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
927 }\r
928 break;\r
929 }\r
930 case NETAPI_NWAL_HANDLE_TRANS_PORT:\r
931 {\r
932 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING)\r
933 {\r
934 p_trans->state =NETAPI_NWAL_HANDLE_STATE_OPEN;\r
935 }\r
936 else if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
937 {\r
938 p_trans->state =NETAPI_NWAL_HANDLE_STATE_IDLE;\r
939 }\r
940 break;\r
941 }\r
942 #if 0\r
943 case TEST_NWAL_HANDLE_TRANS_SEC_ASSOC:\r
944 {\r
945 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
946 {\r
947 testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
948 }\r
949 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
950 {\r
951 System_printf ("Set Security Assoc Close ACK received for trans_id: %d\n",\r
952 testNwLocContext.transInfos[trans_id].transType,trans_id);\r
953 nwal_SystemFlush();\r
954 testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
955 }\r
956 break;\r
957 }\r
958 case TEST_NWAL_HANDLE_TRANS_SEC_POLICY:\r
959 {\r
960 if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_OPEN_PENDING)\r
961 {\r
962 testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_OPEN;\r
963 }\r
964 else if(testNwLocContext.transInfos[trans_id].state == TEST_NWAL_HANDLE_STATE_CLOSE_PENDING)\r
965 {\r
966 System_printf ("Set Security Policy Close ACK received for trans_id: %d\n",\r
967 testNwLocContext.transInfos[trans_id].transType,trans_id);\r
968 nwal_SystemFlush();\r
969 testNwLocContext.transInfos[trans_id].state =TEST_NWAL_HANDLE_STATE_IDLE;\r
970 }\r
971 break;\r
972 }\r
973 #endif\r
974 default:\r
975 {\r
976 printf ("netcp cfg> Invalid transaction type %d for trans_id: %d\n",\r
977 p_trans->transType,trans_id);\r
978 break;\r
979 }\r
980 }\r
981 }\r
982 \r
983 p_local->numPendingCfg--;\r
984 \r
985 if(p_trans->state == NETAPI_NWAL_HANDLE_STATE_IDLE)\r
986 {\r
987 p_trans->inUse = nwal_FALSE;\r
988 }\r
989 \r
990 }\r
991 \r
992 \r
993 /*******************************************************/\r
994 /**************stats reply callback**********************/\r
995 /*******************************************************/\r
996 void netapi_NWALCmdPaStatsReply (nwal_AppId appHandle,\r
997 nwal_TransID_t trans_id,\r
998 paSysStats_t *stats)\r
999 {\r
1000 NetapiNwalTransInfo_t * p_trans;\r
1001 NETAPI_NWAL_LOCAL_CONTEXT_T *p_local=NULL;\r
1002 \r
1003 if(trans_id == NWAL_TRANSID_SPIN_WAIT)\r
1004 {\r
1005 netapi_get_global()->nwal_context.numBogusTransIds++;\r
1006 return;\r
1007 }\r
1008 \r
1009 p_trans= &netapi_get_global()->nwal_context.transInfos[trans_id];\r
1010 p_trans->inUse = nwal_FALSE;\r
1011 p_local =&((NETAPI_HANDLE_T*) (p_trans->netapi_handle))->nwal_local;\r
1012 \r
1013 //save a local copy of some stuff*/\r
1014 p_local->numL2PktsRecvd=stats->classify1.nPackets;\r
1015 p_local->numL3PktsRecvd=stats->classify1.nIpv4Packets;\r
1016 #if 0\r
1017 p_local->numL4PktsRecvd=stats->;\r
1018 p_local->numL4PktsSent=stats->;\r
1019 p_local->TxErrDrop=stats->;\r
1020 #endif\r
1021 //callout result to application !!\r
1022 if (p_local->stats_cb) (*p_local->stats_cb)(p_trans->netapi_handle,stats);\r
1023 \r
1024 } \r
1025 \r