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>
50 #include "trie.h"
51 #include "string.h"
52 #include "netapi.h"
53 #include "pktio.h"
54 #include <sys/resource.h>
56 /*************debug********************/
57 void dump_descr(unsigned long *p, int n)
58 {
59 printf("--------dump of descriptor %d %x\n", n, (int) p);
60 printf("> %x %x %x %x %x %x %x %x\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]);
61 printf("> %x %x %x %x %x %x %x %x\n",p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
62 printf("-----------------------------\n");
63 }
64 /*****************************************/
67 //************for multi pkt burst xfer test in loopback mode
68 #define TX_BURST 4
69 int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;
71 //this device: 10.0.0.100, mac 0x,01,02,03,04,05 and .. 0x6
73 //test packet, setup for loopback (so dest is ourself)
74 static uint8_t testPkt[] = {
76 /* MAC header */
77 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
78 0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04,
79 0x08, 0x00,
81 /* IP header */
82 0x45, 0x00,
83 0x00, 0x6c, /* Length (including this header) */
84 0x00, 0x00, 0x00, 0x00, 0x05, 0x11,
85 0x00, 0x00, /* Header checksum */
86 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64,
88 /* UDP header */
89 0x12, 0x34, 0x05, 0x55,
90 0x00, 0x58, /* Length, including this header */
91 0x00, 0x00, /* Header checksum */
93 /* Payload */
94 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
95 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
96 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
97 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
98 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
99 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
100 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
101 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
102 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
103 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81
105 };
107 #define TEST_PAYLOAD_LEN 80
109 #define TEST_PKT_IP_OFFSET_BYTES 14
110 #define TEST_PKT_UDP_OFFSET_BYTES 34
111 #define TEST_PKT_PLOAD_OFFSET_BYTES 42
112 #define TEST_PKT_UDP_HDR_LEN 8
113 /* Offsets to length fields */
114 #define TEST_PKT_OFFSET_IP_LEN 16
115 #define TEST_PKT_OFFSET_UDP_LEN 38
117 #define TEST_PKT_LEN 122
119 /* The pseudo header checksum of the packet except for the 16 bit length */
120 #define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN 0x0FFC
124 #if 1
125 //#include "arpa/inet.h"
126 long htonl(long x)
127 {
128 long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 | (x&0xff)<<24 ;
129 return temp;
130 }
132 /********************************************************************
133 * FUNCTION PURPOSE: Ones complement addition utility
134 ********************************************************************
135 ********************************************************************/
136 uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)
137 {
138 uint32_t result;
140 result = (uint32_t)v1 + (uint32_t)v2;
141 result = (result >> 16) + (result & 0xffff);
142 result = (result >> 16) + (result & 0xffff);
144 return ((uint16_t)result);
145 }
147 /********************************************************************
148 * FUNCTION PURPOSE: Ones complement checksum utility
149 ********************************************************************
150 ********************************************************************/
151 uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)
152 {
153 uint16_t chksum = 0;
154 uint16_t v;
155 uint32_t i;
156 uint32_t j;
158 for (i = j = 0; i < nwords; i++, j+=2) {
159 v = (p[j] << 8) | p[j+1];
160 chksum = test_utilOnesComplementAdd (chksum, v);
161 }
162 return (chksum);
163 } /* utilOnesCompChkSum */
165 /**************************************************************************************
166 * FUNCTION PURPOSE: Compute ipv4 psudo checksum
167 **************************************************************************************
168 * DESCRIPTION: Compute ipv4 psudo checksum
169 **************************************************************************************/
170 uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)
171 {
172 uint16_t psudo_chksum;
174 psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);
175 psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);
176 psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);
178 return (psudo_chksum);
180 } /* utilGetIpv4PsudoChkSum */
184 #endif
185 typedef struct stats_t
186 {
187 long itx; //initially generated
188 long rx;
189 long tx;
190 long n_bad;
191 long n_new;
192 } STATS_T;
194 typedef struct head_t
195 {
196 long ip[5];
197 long udp[2];
198 } HEAD_T;
200 typedef struct key_t
201 {
202 long src_ip;
203 long dst_ip;
204 short src_port;
205 short dst_port;
206 } KEY_T;
208 unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0
209 unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1
210 nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
211 nwalIpAddr_t OurIp1={ 10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
213 #if 1 //goes with real tx (to laptop)
214 unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,
215 0x00,0x01,0x02,0x03,0x04,0x05,
216 0x08,0x00};
217 unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};
218 #endif
220 #if 0 //goes with loopback
221 unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05,
222 0x00,0x11,0x22,0x33,0x44,0x55,
223 0x08,0x00};
224 #endif
225 #define NE 65536
226 HEAD_T *nat;
228 #define NP 5000
229 int n_pkt = NP;
230 STATS_T stats;
232 Trie * P_trie;
233 HEAD_T pkts[NP];
234 #define PERSLOW 10 //% of pkts that will not be fastpath'd
235 int perslow= PERSLOW;
237 /*******************************************
238 *************NETAPI OBJECTS***************
239 *****************************************/
240 Pktlib_HeapHandle OurHeap;
241 PKTIO_HANDLE_T *our_chan;
242 PKTIO_HANDLE_T *netcp_rx_chan;
243 PKTIO_HANDLE_T *netcp_tx_chan;
244 PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
245 PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
246 PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
248 void house(NETAPI_SCHED_HANDLE_T *s);
249 NETAPI_T netapi_handle;
250 NETAPI_SCHED_HANDLE_T * our_sched;
251 NETAPI_SCHED_CONFIG_T our_sched_cfg={
252 NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50 //every 50 poll loops
253 };
254 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
255 NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock;
256 NETAPI_TIMER_T t1;
257 NETAPI_TIMER_T t2;
258 NETAPI_TIMER_T t3;
260 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
261 int n_fired, //# timers fired
262 NETAPI_TIMER_LIST_T fired_list,
263 uint64_t currentTime);
265 /*************************END NETAPI OBJECTS***********************/
267 #define START_SRC_IP 0x0a00000a
268 #define DST_IP 0xc0a80001
269 #define NEW_START_SRC_IP 0x9eda000a
270 #define DST_PORT 0x555
271 #define START_SRC_PORT 0x1234
272 #define NEW_START_SRC_PORT 100
273 void update_header(HEAD_T * p_head, int len)
274 {
275 unsigned char *p = (unsigned char *) &p_head->udp[1];
276 len -= (20+14);
277 /* update ip checksum */
278 /* update udp checksum */
279 /* update length */
280 *p= (len&0xff00)>>8;
281 *(p+1) = len&0xff;
282 }
284 #if 0
285 void gen_pkts(int np)
286 {
287 int i;
288 int ip = START_SRC_IP &0xff;
289 int port= START_SRC_PORT;
290 //HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},
291 // {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};
292 HEAD_T temp;
293 memcpy(&temp,&testPkt[0],sizeof(HEAD_T));
295 for(i=0;(i<np) && (i<NP);i++)
296 {
297 memcpy(&pkts[i],&temp,sizeof(temp));
298 update_header(&pkts[i],512); /* update checksums etc */
299 /* change template for new pkt */
300 ip+=1;
301 if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }
302 temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);
303 temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);
304 temp.udp[1] = htonl(temp.udp[1]);
306 }
307 n_pkt=np;
308 }
309 #endif
311 void build_table(Trie * p_trie)
312 {
313 int i;
314 int sport=NEW_START_SRC_PORT;
315 HEAD_T temp,temp2;
316 KEY_T key;
318 memcpy(&temp,&testPkt[14],sizeof(temp));
320 //insert entry into trie
321 key.src_ip = temp.ip[3];
322 key.dst_ip = temp.ip[4];
323 key.src_port= (temp.udp[0]&0xffff0000)>>16;
324 key.dst_port= (temp.udp[0]&0x0000ffff);
325 trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[0]); //asociate with nat entry 0
327 //build nat table
328 for(i=0;i<100;i++)
329 {
330 memcpy(&temp2,&testPkt[14],sizeof(temp));
331 temp2.udp[0] = (temp2.udp[0] & 0xffff0000) | sport;
332 memcpy(&nat[i], &temp2, sizeof(temp2));
333 sport+= 1;
334 }
335 }
337 //===========stub transmitter==================
338 void send_pkt(Ti_Pkt *pkt, int len)
339 {
340 //just free pkt. Don't send
341 Pktlib_freePacket((Ti_Pkt*)pkt);
342 return;
343 }
345 //==========stub slow path============
346 void slow_path(Ti_Pkt *pkt, int len)
347 {
348 // debug: check descriptor for validity by verifying that desciptor link field is null as expected\n");
349 {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}
350 //just free pkt
351 Pktlib_freePacket((Ti_Pkt*)pkt);
352 return;
353 }
354 /* check header */
355 struct LastPktInfo
356 {
357 int iface;
358 int ipcsum;
359 int l4csum;
360 } ;
361 static struct LastPktInfo lpInfo;
363 int check_header(HEAD_T * p_head, PKTIO_METADATA_T * p_meta)
364 {
365 if (NWAL_RX_FLAG1_META_DATA_VALID & p_meta->u.rx_meta->rxFlag1)
366 {
367 lpInfo.iface = ((unsigned int)p_meta->u.rx_meta->appId) &0xff; //last byte is interface num
368 lpInfo.ipcsum =(p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_MASK )== NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_ACK ? 1 : 0;
369 lpInfo.l4csum = (p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_MASK )== ((NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_ACK) << NWAL_RX_FLAG1_L4_CHKSUM_VERIFY_SHIFT) ? 1 : 0;
370 }
371 return 1;
372 }
374 #define PKT_LEN 1400
375 void test_alloc_free(int n)
376 {
377 int i;
378 Ti_Pkt * b;
380 for(i=0;i<n;i++)
381 {
382 b=Pktlib_allocPacket(OurHeap,PKT_LEN);
383 Pktlib_freePacket(b);
384 }
385 }
386 /*-----------test driver: gen an input pkt------- */
387 //char buffer[sizeof(HEAD_T)+PKT_LEN];
388 Ti_Pkt * get_pkt(int n, unsigned int *p_len)
389 {
390 int ind;
391 long long temp;
392 Ti_Pkt * b;
393 char * buffer;
394 unsigned int len;
396 if (pktloopback==0)
397 {
398 if (n>=4) return NULL; //just gen pkts to warm swtich, so that it knows
399 //our mac is valid
400 }
401 b=Pktlib_allocPacket(OurHeap,PKT_LEN);
402 if (!b)
403 {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};
405 //debug - way to validate descriptor
406 {Ti_Pkt* k= Pktlib_getNextPacket(b);
407 if(k != 0) {printf(" genpkt, nexpkt != NULL");}}
410 //get pointer to buffer area of packet
411 Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);
413 #if 0
414 if (pktloopback==0)
415 {
416 temp = (long long) rand();
417 temp *= PKT_LEN;
418 temp /= RAND_MAX;
419 temp +=2;
420 *p_len = (int) temp;
421 *p_len = *p_len &0xfffffffe;
422 temp = (long long) rand();
423 temp *= n_pkt;
424 temp /= RAND_MAX;
425 ind = (int) temp;
426 update_header(&pkts[ind],*p_len);
427 //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);
428 memcpy(&buffer[0], &mac_header[0],14);
429 memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T));
430 }
431 else
432 #endif
434 //copy test packet into buffer
435 {
436 memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);
437 *p_len = TEST_PKT_LEN;
438 }
439 return b;
440 }
443 /******************************************************/
444 /******************PKT RECEIVE HANDLER *************************/
445 /******************************************************/
446 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
447 PKTIO_METADATA_T meta[], int n_pkts,
448 uint64_t ts )
449 {
450 int i;
451 int len;
452 int p;
453 HEAD_T * p_res;
454 Ti_Pkt * tip;
455 unsigned int templen;
456 int err;
457 KEY_T key;
458 char * p_pkt;
459 HEAD_T * p_head;
460 HEAD_T temp_head;
462 p_head=&temp_head;
464 //debug
465 #if 0
466 if (n_pkts != TX_BURST) {
467 printf("recv_cb, txsofar=%d rxsofar=%d np = %d, NOT %d\n",
468 stats.itx, stats.rx, n_pkts,TX_BURST);
469 our_stats_cb(netapi_handle,NULL);
470 }
471 #endif
472 //test_alloc_free(7);
473 //printf("recv start\n");
475 /* loop over received pkts */
476 for(i=0;i<n_pkts;i++)
477 {
478 tip = p_recv[i];
479 Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
480 len = Pktlib_getPacketLen(tip);//real length
482 //debug: validate descriptor */
483 if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}
484 //debug printf("recv pkt, len=%d %d\n", len, templen);
485 stats.rx+=1;
487 #ifdef DEBUG_DESC
488 if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}
489 else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}
490 #endif
493 /* check header */
494 memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
495 if (!check_header(p_head,&meta[i])) {
496 stats.n_bad+=1;Pktlib_freePacket(tip); continue;
497 }
499 /* lookup flow */
500 key.src_ip = p_head->ip[3];
501 key.dst_ip = p_head->ip[4];
502 key.src_port= (p_head->udp[0]&0xffff0000)>>16;
503 key.dst_port= (p_head->udp[0]&0x0000ffff);
504 p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));
505 if (!p_res) { stats.n_new+=1; slow_path(tip, len); continue;}
507 /* copy header */
508 memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));
510 memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));
511 /* update_mac(&p_pkt[0]); */
513 /* 'simulate' send pkt */
514 send_pkt(tip,len);
515 stats.tx+=1;
516 }
517 //printf("recv done\n");
518 }
520 //timer callback
521 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
522 int n_fired, //# timers fired
523 NETAPI_TIMER_LIST_T fired_list,
524 uint64_t currentTime)
525 {
526 int i;
527 NETAPI_TIMER_T tx;
528 int cookie;
529 int err;
530 unsigned long long et;
531 printf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);
532 tx = netapi_TimerGetFirst(fired_list);
533 for(i=0;i<n_fired;i++)
534 {
535 cookie = (int) netapi_TimerGetCookie(tx);
536 et = netapi_TimerGetTs(tx); //debug
537 printf(" timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);
538 if (cookie ==1)
539 t1 = netapi_TimerGroupStartTimer(
540 th,
541 (void *) 1,
542 100LL, //timer group tics
543 &err);
544 else if (cookie ==2)
545 t2 = netapi_TimerGroupStartTimer(
546 th,
547 (void *) 2,
548 200LL, //timer group ticks
549 &err);
550 else
551 {
552 t3 = netapi_TimerGroupStartTimer(
553 th,
554 (void *) 3,
555 300LL, //timer group ticks
556 &err);
557 //cancel 1 and restart 1
558 netapi_TimerGroupCancel(th,t1,&err);
559 t1 = netapi_TimerGroupStartTimer(
560 th,
561 (void *) 1,
562 100LL, //timer group ticks
563 &err);
564 }
565 tx = netapi_TimerGetNext(fired_list,tx);
566 }
567 }
570 static int np2process = NP;
571 /******************************************************
572 * stats callback
573 *******************************************************/
574 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
575 {
576 uint32_t numFreeDataPackets;
577 uint32_t numZeroBufferPackets;
578 uint32_t numPacketsinGarbage;
580 printf("stats @ %lld\n", netapi_getTimestamp());
581 if(pPaStats)
582 {
583 printf("C1 number of packets: %d\n", pPaStats->classify1.nPackets);
584 printf("C1 number IPv4 packets: %d\n", pPaStats->classify1.nIpv4Packets);
585 //printf("C1 number llc/snap fail: %d\n", pPaStats->classify1.nLlcSnapFail);
586 printf("C1 number table matched: %d\n", pPaStats->classify1.nTableMatch);
587 printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
588 printf ("C1 number of parse fail: %d\n",pPaStats->classify1.nParseFail);
589 printf("C1 number of command failures: %d\n", pPaStats->classify1.nCommandFail);
590 printf("C1 number invalid reply dests: %d\n", pPaStats->classify1.nInvalidComReplyDest);
591 printf ("C1 number of silent discard: %d\n",pPaStats->classify1.nSilentDiscard);
592 printf("C1 number of invalid control: %d\n", pPaStats->classify1.nInvalidControl);
593 printf ("C1 number of invalid states: %d\n",pPaStats->classify1.nInvalidState);
594 printf ("C1 number of system fails: %d\n",pPaStats->classify1.nSystemFail);
595 printf ("C2 number parse failed : %d\n",pPaStats->classify2.nParseFail);
596 printf ("C2 number Invld Header : %d\n",pPaStats->classify2.nInvldHdr);
597 printf ("C2 number udp : %d\n",pPaStats->classify2.nUdp);
598 printf ("C2 number tcp : %d\n",pPaStats->classify2.nTcp);
599 printf ("C2 number cmd fail : %d\n",pPaStats->classify2.nCommandFail);
600 printf ("C2 number silent drop : %d\n",pPaStats->classify2.nSilentDiscard);
601 printf ("C2 number invalid cntrl : %d\n\n",pPaStats->classify2.nInvalidControl);
602 }
603 Pktlib_getHeapStats(OurHeap, &numFreeDataPackets,
604 &numZeroBufferPackets, &numPacketsinGarbage);
605 printf("heap stats> #free=%d #zb=%d #garbage=%d\n", numFreeDataPackets,
606 numZeroBufferPackets, numPacketsinGarbage);
607 //debug = dump timer polling stats
608 dump_poll_stats();
611 }
613 //******************************************************
614 //use scheduling housekeeping callback to generate pkts
615 //******************************************************
616 void house(NETAPI_SCHED_HANDLE_T * s)
617 {
618 Ti_Pkt * tip;
619 unsigned int len;
620 nwalTxPktInfo_t meta_tx={0};
621 PKTIO_METADATA_T meta = {PKTIO_META_TX,0};
622 int err;
623 static int house_pkts_gened=0;
624 int p;
625 unsigned char * pIpHdr,* pData;
627 for(p=0;p<TX_BURST;p++) {
628 //reguest stats
629 if ((house_pkts_gened>0) && (! (house_pkts_gened%400)) )
630 {
631 printf("net_test> request stats at n=%d \n",house_pkts_gened);
632 netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err);
633 if (err!=0) {printf("stats req failed\n");}
634 }
637 if (house_pkts_gened >= np2process+ 100)
638 {
639 //shutdown
640 netapi_schedShutdown(s,NULL,&err);
641 continue;
642 }
644 else if (house_pkts_gened >= np2process) { house_pkts_gened+=1; continue;}
647 /* manufacture a pkt to transmit */
648 tip = get_pkt(house_pkts_gened, &len);
649 if(!tip) { house_pkts_gened +=1; continue; }
651 /* set the pkt length */
652 Pktlib_setPacketLen(tip, len);
654 /* set up meta data */
655 meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM);
656 meta_tx.startOffset = 0;
657 meta_tx.pktLen = len;
658 meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;
659 meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;
660 meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;
661 meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;
662 meta_tx.ploadLen = TEST_PAYLOAD_LEN;
664 Pktlib_getDataBuffer(tip,&pData,&len);
665 pIpHdr = pData + meta_tx.ipOffBytes;
666 meta_tx.pseudoHdrChecksum =
667 test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
669 /* post it to netcp tx channel*/
670 meta.u.tx_meta=&meta_tx;
671 #ifdef DEBUG_DESC
672 if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);
673 else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);
674 #endif
675 pktio_send(netcp_tx_chan,tip,&meta,&err);
676 if (err == 0) stats.itx +=1;
678 house_pkts_gened +=1;
679 }
680 }
683 /***************************************
684 ********** test driver*****************
685 ***************************************/
686 int main(int argc, char **argv)
687 {
688 int err;
689 rlim_t oss,ss = 1024*1024;
690 struct rlimit rl;
692 err= getrlimit(RLIMIT_STACK,&rl);
693 if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");
694 #if 0
695 rl.rlim_cur = ss;
696 err=setrlimit(RLIMIT_STACK,&rl);
697 if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
698 #endif
700 if (argc>=2) np2process = atoi(argv[1]);
701 if (np2process<0) np2process = NP; /* default */
702 if (argc==3) perslow = atoi(argv[2]);
703 if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default
704 if (argc>3) {printf("net_test <no of pkts to process> <percent slow path>\n"); exit(1);}
707 //real mode, so update our test packet mac header and ip header
708 if (pktloopback==0)
709 {
710 memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address
711 memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses
712 }
714 /*******************************************/
715 /*************NETAPI STARTUP****************/
716 /*******************************************/
718 /* create netapi */
719 netapi_handle = netapi_init(NETAPI_SYS_MASTER);
721 /* open the main heap */
722 OurHeap = Pktlib_findHeapByName("netapi");
723 if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
725 /* create a pktio channel */
726 our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb, &our_chan_cfg,&err);
727 if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
729 /* open netcp default tx, rx queues */
730 netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err);
731 if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
732 netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg, &err);
733 if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
736 /* create scheduler instance */
737 our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
738 if (!our_sched) {printf("sched create failed\n"); exit(1);}
740 /* add mac intefaces */
741 netcp_cfgCreateMacInterface(
742 netapi_handle,
743 &mac0[0],
744 0,0,
745 (NETCP_CFG_ROUTE_HANDLE_T) NULL,
746 (NETCP_CFG_VLAN_T ) NULL , //future
747 1,
748 &err);
749 if (err) {printf("addmac0 failed %d\n",err); exit(1); }
751 //attach an IP to this interface
752 netcp_addIp(
753 netapi_handle,
754 0,
755 nwal_IPV4,
756 &OurIp0,
757 NULL, //all IP
758 (NETCP_CFG_ROUTE_HANDLE_T) NULL,
759 &err
760 );
761 if (err) {printf("addip0 failed %d\n",err); exit(1); }
762 #if 1
763 //create a 2nd mac instance
764 netcp_cfgCreateMacInterface(
765 netapi_handle,
766 &mac1[0],
767 1,1,
768 (NETCP_CFG_ROUTE_HANDLE_T) NULL,
769 (NETCP_CFG_VLAN_T ) NULL , //future
770 1,
771 &err);
772 if (err) {printf("addmac1 failed %d\n",err); exit(1); }
774 //attach an IP to this interface
775 netcp_addIp(
776 netapi_handle,
777 1,
778 nwal_IPV4,
779 &OurIp1,
780 NULL, //all IP
781 (NETCP_CFG_ROUTE_HANDLE_T) NULL,
782 &err
783 );
784 if (err) {printf("addip1 failed %d\n",err); exit(1); }
786 #endif
788 ourTimerBlock = netapi_TimerGroupCreate(
789 netapi_handle,
790 "our1sttimer",
791 our_timer_cb,
792 0, //1 if timers local to thread
793 0, //1 if expect to cancel
794 netapi_getTicksPerSec()/1000, /* 1 msc resolution for these timers */
795 netapi_getTicksPerSec()/5000, /* would like .5 msc tolerence */
796 10, //small # of timers to test garbage collection
797 &err);
798 if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}
800 //start a couple of timers
801 t1 = netapi_TimerGroupStartTimer(
802 ourTimerBlock,
803 (void *) 1,
804 100LL, //timer group ticks
805 &err);
806 if (err) {printf("timerstart failed %d\n");}
807 t2 = netapi_TimerGroupStartTimer(
808 ourTimerBlock,
809 (void *) 2,
810 200LL, //timer group ticks
811 &err);
812 if (err) {printf("timerstart failed %d\n");}
813 t3 = netapi_TimerGroupStartTimer(
814 ourTimerBlock,
815 (void *) 3,
816 300LL, //timer group ticks
817 &err);
818 if (err) {printf("timerstart failed %d\n");}
821 /*********************************************/
822 /*****************end NETAPI STARTUP**********/
823 /*********************************************/
826 /********************************************
827 * Basic pkt loopback test
828 *********************************************/
831 /* create TRIE */
832 P_trie = trie_new();
833 if (!P_trie) {printf("trie alloc failed\n"); exit(1);}
835 nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));
836 if (!nat) {printf("malloc of nat table failed\n"); exit(1);}
838 //gen_pkts(np2process<NP ? np2process:NP);
839 n_pkt= np2process;
841 /* build table */
842 build_table(P_trie);
845 /* processing loop: get pkt, check it, look up in table, copy new header,
846 send packet */
847 srand((unsigned) np2process);
850 /*********************************************/
851 /**************Entry point into scheduler ****/
852 /*********************************************/
853 netapi_schedWaitForEvents(our_sched, &err);
855 /* done */
856 printf("done: itx=%d rx=%d tx=%d bad=%d slow=%d\n",stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new);
857 our_stats_cb(netapi_handle, NULL);
859 netapi_shutdown(netapi_handle);
861 }