1 /******************************************
2 * File: net_test.c
3 * Purpose: test app for netapi
4 **************************************************************
5 * FILE: net_test.c
6 *
7 * DESCRIPTION: netapi user space transport
8 * library test application
9 *
10 * REVISION HISTORY: rev 0.0.1
11 *
12 * Copyright (c) Texas Instruments Incorporated 2010-2011
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the
24 * distribution.
25 *
26 * Neither the name of Texas Instruments Incorporated nor the names of
27 * its contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 *****************************************/
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47 #include <string.h>
48 #include <signal.h>
49 #include <pthread.h>
51 #include "net_test.h"
52 #include "trie.h"
53 #include "string.h"
55 #include <sys/resource.h>
57 #include <ti/drv/sa/salld.h>
58 #include <ti/drv/pa/pa.h>
60 #include "net_test_util.h"
62 extern int QUIT;
64 /* Global definitions */
65 #ifdef MULTI_THREAD
66 cpu_set_t cpu_set;
67 #endif
69 netTestConfig_t netTestCfg;
70 static netTestConfigFile_t config_file;
72 char input_file_name[] = "net_test_config.txt";
74 nwal_RetValue nwalRetVal;
75 Pktlib_HeapHandle ourHeap;
76 Pktlib_HeapHandle specialSmall;
77 Pktlib_HeapHandle specialLarge;
79 PKTIO_HANDLE_T *netcp_rx_chan;
80 PKTIO_HANDLE_T *netcp_rx_chan2;
81 PKTIO_HANDLE_T *netcp_tx_chan;
82 PKTIO_HANDLE_T *netcp_sb_tx_chan;
83 PKTIO_HANDLE_T *netcp_sb_rx_chan;
84 PKTIO_CFG_T our_chan_cfg={PKTIO_RX_TX, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
85 PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};
86 PKTIO_CFG_T netcp_rx_cfg2={PKTIO_RX, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};
87 PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};
88 PKTIO_CFG_T netcp_sb_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};
89 PKTIO_CFG_T netcp_sb_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};
91 NETCP_CFG_EXCEPTION_PKT_T expPkt_appid;
92 static hplib_spinLock_T stats_lock;
94 Trie * P_trie;
95 Trie *p_trie_sa_rx;
96 Trie *p_trie_sa_tx;
99 #include "router.c"
100 extern Trie * our_router;
101 extern OUR_ROUTE_T routes[];
103 unsigned int ip[MAX_ROUTES]={BE(0x0a0100c8),BE(0x0a00000a),BE(0x0a02000a),BE(0xc0a8010a),BE(0x9eda6719)};
105 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
106 PKTIO_METADATA_T meta[], int n_pkts,
107 uint64_t ts );
110 extern STATS_T stats[TUNE_NETAPI_NUM_CORES];
111 extern paSysStats_t netcp_stats;
113 /*******************************************
114 *************NETAPI OBJECTS***************
115 *****************************************/
116 static NETAPI_CFG_T our_netapi_default_cfg=
117 {
118 TUNE_NETAPI_PERM_MEM_SZ,
119 128, //start of packet offset for hw to place data on rx for default flow
120 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
121 TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use
122 TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap
123 64, //#descriptors w/o buffers in default heap
124 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128, //size of buffers in default heap
125 128 , //tail room
126 256 //extra room
127 };
131 void house(NETAPI_SCHED_HANDLE_T *s);
132 NETAPI_T netapi_handle;
133 NETAPI_SCHED_HANDLE_T * our_sched;
134 #ifdef MULTI_THREAD
135 NETAPI_SCHED_HANDLE_T * scheduler[TUNE_NETAPI_NUM_CORES];
136 #endif
137 NETAPI_SCHED_CONFIG_T our_sched_cfg={
138 NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000 //every 5000000 poll loops
139 };
142 NETCP_CFG_IP_T ip_rule0;
143 NETCP_CFG_IP_T ip_rule1;
145 PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};
147 /* security objects. (for loopback mode) */
148 netTestSA_t sa_info[MAX_SEC_INDEX];
151 NETCP_CFG_IPSEC_POLICY_T rx_policy[MAX_SEC_INDEX];
156 /*************************END NETAPI OBJECTS***********************/
158 void update_header(HEAD_T * p_head, int len)
159 {
160 unsigned char *p = (unsigned char *) &p_head->udp[1];
161 len -= (20+14);
162 /* update ip checksum */
163 /* update udp checksum */
164 /* update length */
165 *p= (len&0xff00)>>8;
166 *(p+1) = len&0xff;
167 }
169 #ifdef MULTI_THREAD
170 NETAPI_T worker_nh[TUNE_NETAPI_NUM_CORES];
171 void slow_path_thread(int coreid)
172 {
173 int err;
174 PKTIO_HANDLE_T *rx_chan;
175 PKTIO_HANDLE_T *tx_chan;
176 PKTIO_HANDLE_T *sb_tx_chan;
177 PKTIO_HANDLE_T *sb_rx_chan;
181 Debug_printf("slow_path_thread, mypid: %d, core_id %d\n", gettid(), coreid);
183 CPU_ZERO( &cpu_set);
184 #ifdef CORTEX_A15
185 CPU_SET( coreid, &cpu_set);
186 hplib_utilSetupCore(coreid, &cpu_set);
187 #else
188 CPU_SET( 0, &cpu_set);
189 hplib_utilSetupCore(coreid+1, &cpu_set);
190 #endif
191 worker_nh[coreid]=netapi_init(NETAPI_CORE_MASTER,NULL);
193 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) worker_nh[coreid];
195 /* open netcp default tx, rx queues */
196 tx_chan = pktio_open(worker_nh[coreid], NETCP_TX, NULL, &netcp_tx_cfg, &err);
198 rx_chan = pktio_open(worker_nh[coreid], NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg, &err);
202 netapi_setCookie(worker_nh[coreid],(void*)coreid);
204 scheduler[coreid] =netapi_schedOpen(worker_nh[coreid],&our_sched_cfg, &err);
205 if (!scheduler[coreid])
206 {
207 Debug_printf("sched create failed for core%d\n",coreid);
208 exit(1);
209 }
210 scheduler[coreid]->config.yield = FALSE;
211 scheduler[coreid]->config.pollGarbageQ = TRUE;
212 scheduler[coreid]->config.pollCtrlQ = TRUE;
213 /*********************************************/
214 /**************Entry point into scheduler ****/
215 /*********************************************/
216 netapi_schedRun(scheduler[coreid], &err);
217 Debug_printf(">net_test: core %d worker thread done\n",coreid);
219 pktio_close(tx_chan, &err);
220 pktio_close(rx_chan, &err);
221 netapi_shutdown(worker_nh[coreid]);
222 }
224 void fast_path_thread(int coreid)
225 {
226 int err;
227 PKTIO_HANDLE_T *rx_chan;
228 PKTIO_HANDLE_T *tx_chan;
229 PKTIO_HANDLE_T *sb_tx_chan;
230 PKTIO_HANDLE_T *sb_rx_chan;
232 #ifdef CORTEX_A15
233 CPU_SET( coreid, &cpu_set);
234 hplib_utilSetupCore(coreid, &cpu_set);
235 #else
236 CPU_SET( 0, &cpu_set);
237 hplib_utilSetupCore(coreid + 1, &cpu_set);
238 #endif
239 worker_nh[coreid]=netapi_init(NETAPI_CORE_MASTER,NULL);
241 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) worker_nh[coreid];
243 /* open netcp default tx, rx queues */
244 tx_chan = pktio_open(worker_nh[coreid], NETCP_TX, NULL, &netcp_tx_cfg, &err);
247 rx_chan = pktio_open(worker_nh[coreid], NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg, &err);
248 netapi_setCookie(worker_nh[coreid],(void*)coreid);
250 scheduler[coreid] =netapi_schedOpen(worker_nh[coreid],&our_sched_cfg, &err);
251 if (!scheduler[coreid])
252 {
253 Debug_printf("sched create failed for core%d\n",coreid);
254 exit(1);
255 }
257 /*********************************************/
258 /**************Entry point into scheduler ****/
259 /*********************************************/
260 scheduler[coreid]->config.yield = FALSE;
261 scheduler[coreid]->config.pollGarbageQ = FALSE;
262 scheduler[coreid]->config.pollCtrlQ = FALSE;
263 //sleep(100000);
264 netapi_schedRun(scheduler[coreid], &err);
265 Debug_printf(">net_test: core %d worker thread done\n",coreid);
266 pktio_close(tx_chan, &err);
267 pktio_close(rx_chan, &err);
268 netapi_shutdown(worker_nh[coreid]);
269 \r}
271 #endif
273 /***************************************
274 ********** test driver*****************
275 ***************************************/
276 int main(int argc, char **argv)
277 {
278 int err,i;
279 Pktlib_HeapCfg heapCfg;
280 rlim_t oss,ss = 1024*1024;
281 struct rlimit rl;
282 int32_t errCode;
283 Pktlib_HeapIfTable* pPktifTable;
284 /* Local Per Process default resourcese maintained at NWAL */
285 nwalLocCxtInfo_t nwalLocCxt;
287 FILE * fpr = NULL;
290 err= getrlimit(RLIMIT_STACK,&rl);
291 if (!err) Debug_printf(" stack limit = %d\n",rl.rlim_cur); else Debug_printf("getrlimit failed\n");
293 /* install signal handler for ^c */
294 signal(SIGINT,mysig);
296 fpr = fopen(input_file_name, "r");
297 if (fpr == NULL)
298 {
299 Debug_printf("Error in opening %s input file\n", input_file_name);
300 exit(1);
301 }
302 else
303 {
304 memset(&config_file, 0, sizeof(netTestConfigFile_t));
305 memset(&netTestCfg, 0, sizeof(netTestConfig_t));
306 parse_config_file(fpr,&config_file);
307 }
309 memset(&sa_info, 0, sizeof(sa_info));
311 #ifdef MULTI_THREAD
312 /* assign main net_test thread to run on core 0 */
313 CPU_ZERO( &cpu_set);
314 CPU_SET( 0, &cpu_set);
315 hplib_utilSetupCore(0, &cpu_set);
316 #endif
317 /* create netapi */
318 netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
320 netcp_cfgExceptions(netapi_handle, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_DISCARD, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
321 expPkt_appid = netcp_cfgExceptions(netapi_handle, 7, NETCP_CFG_ACTION_TO_SW, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
323 /* open the main heap */
324 ourHeap = Pktlib_findHeapByName("netapi");
325 if (!ourHeap)
326 {
327 Debug_printf("Pktlib_findHeapByName() fail\n");
328 exit(1);
329 }
331 /* create two secondary heaps */
332 /* Initialize the heap configuration. */
333 memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
335 pPktifTable = netapi_getPktlibIfTable();
336 /* Populate the heap configuration */
337 heapCfg.name = "netapi-small";
338 heapCfg.memRegion = NETAPI_GLOBAL_REGION;
339 heapCfg.sharedHeap = 1;
340 heapCfg.useStarvationQueue = 0;
341 heapCfg.dataBufferSize = 512;
342 heapCfg.numPkts = 64;
343 heapCfg.numZeroBufferPackets= 0;
344 heapCfg.heapInterfaceTable.data_malloc = pPktifTable->data_malloc;
345 heapCfg.heapInterfaceTable.data_free = pPktifTable->data_free;
346 heapCfg.dataBufferPktThreshold = 0;
347 heapCfg.zeroBufferPktThreshold = 0;
349 specialSmall = Pktlib_createHeap(&heapCfg, &errCode);
350 heapCfg.name = "netapi-big";
351 heapCfg.dataBufferSize = 1600;
352 specialLarge = Pktlib_createHeap(&heapCfg, &errCode);
353 //register these heaps so poll routine will include their garbage queues.
354 netapi_registerHeap(netapi_handle, specialSmall);
355 netapi_registerHeap(netapi_handle, specialLarge);
357 /* open netcp default tx, rx queues */
358 netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err);
359 if (!netcp_tx_chan)
360 {
361 Debug_printf("pktio open TX failed err=%d\n",err);
362 exit(1);
363 }
364 netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg, &err);
365 if (!netcp_rx_chan)
366 {
367 Debug_printf("pktio open RX failed err=%d\n",err);
368 exit(1);
369 }
371 Debug_printf("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder());
372 /* create scheduler instance */
373 our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
374 if (!our_sched) {Debug_printf("sched create failed\n"); exit(1);}
377 /*create net_test MAC interfaces, attach IP to created MAC interfaces */
378 create_interfaces(&ip_rule0, &ip_rule1);
380 p_trie_sa_rx = trie_new();
381 p_trie_sa_tx = trie_new();
382 if (!p_trie_sa_rx || !p_trie_sa_tx)
383 {Debug_printf("trie alloc for SA failed\n"); exit(1);}
385 /* Create RX SA's, RX Policy and TX SA's */
386 create_sec_associations(netcp_sb_rx_chan, netcp_sb_tx_chan,netcp_tx_chan);
389 #ifdef MULTI_THREAD
390 {
391 CPU_ZERO( &cpu_set );
392 pthread_t *thrs;
393 int procs =2; //get this from config eventually
394 char c;
395 thrs = malloc( sizeof( pthread_t ) * procs );
396 if (thrs == NULL)
397 {
398 perror( "malloc" );
399 return -1;
400 }
401 Debug_printf( "Starting %d threads...\n", procs );
403 if (pthread_create( &thrs[0], NULL, (void*)slow_path_thread,
404 (void *)0 ))
405 {
406 perror( "pthread_create" );
407 exit(1);
408 }
409 #if 1
410 if (pthread_create( &thrs[1], NULL, (void*)fast_path_thread,
411 (void *)1 ))
412 {
413 perror( "pthread_create" );
414 exit(1);
415 }
416 #endif
417 //this thread of execution (main) now just waits on user input
418 for(;;)
419 {
420 Debug_printf(">");
421 c=getchar();
422 if (c=='q') {QUIT=1;break;}
423 else if (c=='s') our_stats_cb(netapi_handle, &netcp_stats);
424 else if (c=='h') Debug_printf("'q' to quit, 's' for stats, 'h' for help\n");
425 }
427 //wait for completion
428 Debug_printf("main task now pending on slow/fast path completion\n");
429 for (i = 0; i < procs; i++)
430 pthread_join( thrs[i], NULL );
432 free( thrs );
433 }
434 #else
435 /*********************************************/
436 /**************Entry point into scheduler ****/
437 /*********************************************/
438 netapi_schedRun(our_sched, &err);
440 #endif
442 /* done */
443 our_stats_cb(netapi_handle, NULL);
447 /*************************************************
448 ************CLEAN UP****************************
449 ************************************************/
452 delete_sec_associations();
453 delete_interfaces( &ip_rule0, &ip_rule1);
455 //close pktio channels we opened
456 pktio_close(netcp_tx_chan ,&err);
457 pktio_close(netcp_rx_chan ,&err);
458 netapi_shutdown(netapi_handle);
459 }
461 static inline void send_it(Ti_Pkt *tip, int len, ROUTE_SEC_T * p_sec, int out_port)
462 {
463 unsigned long st1;
464 unsigned long st2;
465 int err=0;
466 PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
467 nwalTxPktInfo_t meta_tx2={0};
468 st1=hplib_mUtilGetPmuCCNT();
469 #ifdef MULTI_THREAD
470 int coreid=Osal_nwalGetProcId(); //who we are(thread local)
471 //int coreid = our_core;
472 #else
473 int coreid=0;
474 #endif
475 if (len<60)
476 {
477 unsigned int templen;
478 char * p_pkt;
479 len=60;
480 Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
481 Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
482 stats[coreid].tx_min+=1;
483 }
484 Pktlib_setPacketLen(tip,len);
485 meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
486 meta_tx2.startOffset = 0;
487 meta_tx2.ipOffBytes = 14;
488 meta_tx2.ploadLen = len ;
489 meta_tx2.enetPort=out_port;
490 if(p_sec)
491 {
492 meta_tx2.txFlag1 |= NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO ;
493 meta2.sa_handle=p_sec->tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
494 meta_tx2.saOffBytes=14+20;
495 meta_tx2.saPayloadLen=len-14-20; //don't include tag, mac and outer header
496 stats[coreid].sec_tx+=1;
497 }
498 meta2.u.tx_meta=&meta_tx2;
499 pktio_send(netcp_tx_chan,tip,&meta2,&err);
500 stats[coreid].tx +=1;
501 st2=hplib_mUtilGetPmuCCNT();
502 stats[coreid].send_cycles += (unsigned long long) (st2-st1);
503 }
504 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
505 PKTIO_METADATA_T meta[], int n_pkts,
506 uint64_t ts )
507 {
508 int i;
509 int len;
510 int p;
511 Ti_Pkt * tip;
512 unsigned int templen;
513 char * p_pkt;
514 HEAD_T temp_head;
515 unsigned int appid;
516 IP_HEAD_T th;
517 ROUTE_SEC_T *sec_data=NULL;
518 unsigned long t1;
519 unsigned long t2;
520 unsigned long long ct1;
521 unsigned long long ct2;
522 unsigned short ip_pl;
523 unsigned long long n_c_ops;
524 int ifno;
525 int out_port;
526 #ifdef MULTI_THREAD
527 int coreid=Osal_nwalGetProcId(); //who we are(thread local)
528 //int coreid = our_core;
529 #else
530 int coreid=0;
531 #endif
532 t1=hplib_mUtilGetPmuCCNT();
533 ct1 =Osal_cache_op_measure(&n_c_ops);
534 for(i=0;i<n_pkts;i++)
535 {
536 ifno = ((unsigned int)meta[i].u.rx_meta->appId)&0xff;
537 if(coreid<TUNE_NETAPI_NUM_CORES) stats[coreid].rx+=1;
538 if (ifno < TUNE_NETAPI_MAX_NUM_MAC) stats[coreid].if_rx[ifno]+=1;
539 tip = p_recv[i];
540 Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
541 len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
542 stats[coreid].rx+=1;
543 appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;
544 switch(appid)
545 {
546 case(NETAPI_NETCP_MATCH_IPSEC):
547 case(NETAPI_NETCP_MATCH_IPSEC_POLICY):
548 {
549 int tailen=12+2;
550 memcpy(&temp_head,&p_pkt[14],sizeof(HEAD_T));
551 if (!check_header(&temp_head,&meta[i])) {
552 stats[coreid].n_bad+=1;
553 Pktlib_freePacket(tip);
554 continue;
555 }
556 tailen+=p_pkt[len-12-2]; //padding length (12)should come from sec_ptr
557 p_pkt = &p_pkt[8+16+20]; //16= iv len, should come from sec_ptr
558 len -= (8+16+20+tailen); //16= iv len should come from sec ptr
560 //now check inner headder.
561 memcpy(&th,&p_pkt[14],20);
562 if (!check_header(&temp_head,&meta[i])) {
563 stats[coreid].n_bad+=1;
564 Pktlib_freePacket(tip);
565 continue;
566 }
567 Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
568 Pktlib_setPacketLen(tip,len);
570 if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data,&out_port)<0)
571 {
572 stats[coreid].n_bad+=1;
573 Pktlib_freePacket(tip);
574 }
575 else
576 {
577 send_it(tip,len,sec_data,out_port);
578 }
579 break;
580 }
581 case(NETAPI_NETCP_MATCH_GENERIC_MAC):
582 if((p_pkt[12]!=0x8)||(p_pkt[13]!=0x00))
583 {
584 stats[coreid].n_new+=1;
585 Pktlib_freePacket(tip);
586 continue;
587 }
588 if (!check_header(&temp_head,&meta[i]))
589 {
590 stats[coreid].n_bad+=1;
591 Pktlib_freePacket(tip);
592 continue;
593 }
594 memcpy(&th,&p_pkt[14],20);
595 ip_pl= (((unsigned char *)&th.w1)[2]<<8) | ((unsigned char *)&th.w1)[3];
596 if ((ip_pl+14)<60)
597 {
598 len-= (60-(ip_pl+14));
599 stats[coreid].rx_min+=1;
600 }
601 Pktlib_setPacketLen(tip,len);
602 if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data,&out_port)<0)
603 {
604 stats[coreid].n_bad+=1;
605 Pktlib_freePacket(tip);
606 }
607 else
608 {
609 send_it(tip,len,sec_data,out_port);
610 }
611 break;
612 case(NETAPI_NETCP_MATCH_GENERIC_IP):
613 Pktlib_freePacket(tip);
614 stats[coreid].n_new=1;
615 break;
616 default:
617 stats[coreid].n_new+=1;
618 Pktlib_freePacket(tip);
619 break;
620 }
621 }
622 t2=hplib_mUtilGetPmuCCNT();
623 ct2 =Osal_cache_op_measure(&n_c_ops);
624 stats[coreid].app_cycles += (unsigned long long) (t2-t1);
625 stats[coreid].tx_cache_cycles += (unsigned long long) (ct2-ct1);
626 return;
627 }