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 //IPSEC MODE(only choose one rx and one tx)
57 #define IPSEC_MODE_RX_INFLOW
58 #define IPSEC_MODE_TX_INFLOW
59 //#define IPSEC_MODE_RX_SIDEBAND
60 //#define IPSEC_MODE_TX_SIDEBAND
62 //#define TEST_TIMERS
64 /*************debug********************/
65 void dump_descr(unsigned long *p, int n)
66 {
67 printf("--------dump of descriptor %d %x\n", n, (int) p);
68 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]);
69 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]);
70 printf("-----------------------------\n");
71 }
72 void dump_header(unsigned long *p, int n, int a, int r)
73 {
74 printf("--------dump of header %d %x appID=%x flag1=%x\n", n, (int) p,a,r);
75 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]);
76 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]);
77 printf("> %x %x %x %x %x %x %x %x\n",p[16],p[17],p[18],p[19],p[20],p[21],p[22],p[23]);
78 printf("> %x %x %x %x %x %x %x %x\n",p[24],p[25],p[26],p[27],p[28],p[29],p[30],p[31]);
79 printf("-----------------------------\n");
80 }
82 /*****************************************/
85 //************for multi pkt burst xfer test in loopback mode
86 #define TX_BURST 800
87 int pktloopback=TUNE_NETAPI_NWAL_ENABLE_PASS_LOOPBACK;
88 nwalTxPSCmdInfo_t flowPSCmdInfo;
90 //this device: 10.0.0.100, mac 0x,01,02,03,04,05 and .. 0x6
92 //test packet, setup for loopback (so dest is ourself)
93 static uint8_t testPkt[] = {
95 /* MAC header */
96 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
97 0x00, 0xe0, 0xa6, 0x66, 0x57, 0x04,
98 0x08, 0x00,
100 /* IP header */
101 0x45, 0x00,
102 0x00, 0x6c, /* Length (including this header) */
103 0x00, 0x00, 0x00, 0x00, 0x05, 0x11,
104 0x00, 0x00, /* Header checksum */
105 0x0a, 0x00, 0x00, 0x0a, 0x0a, 0x00, 0x00, 0x64,
107 /* UDP header */
108 0x12, 0x34, 0x05, 0x55,
109 0x00, 0x58, /* Length, including this header */
110 0x00, 0x00, /* Header checksum */
112 /* Payload */
113 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
114 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41,
115 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
116 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
117 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
118 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61,
119 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
120 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
121 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
122 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81
124 };
126 #define TEST_PAYLOAD_LEN 80
128 #define TEST_PKT_IP_OFFSET_BYTES 14
129 #define TEST_PKT_UDP_OFFSET_BYTES 34
130 #define TEST_PKT_PLOAD_OFFSET_BYTES 42
131 #define TEST_PKT_UDP_HDR_LEN 8
132 /* Offsets to length fields */
133 #define TEST_PKT_OFFSET_IP_LEN 16
134 #define TEST_PKT_OFFSET_UDP_LEN 38
136 #define TEST_PKT_LEN 122
138 /* The pseudo header checksum of the packet except for the 16 bit length */
139 #define TEST_PKT_PSEUDO_HDR_CHKSUM_SANS_LEN 0x0FFC
141 void example_fast_poll( PKTIO_HANDLE_T * p_pktio);
143 #if 1
144 //#include "arpa/inet.h"
145 long htonl(long x)
146 {
147 long temp = (x&0xff000000)>>24 | (x&0xff0000)>>8 | (x&0xff00)<<8 | (x&0xff)<<24 ;
148 return temp;
149 }
151 /********************************************************************
152 * FUNCTION PURPOSE: Ones complement addition utility
153 ********************************************************************
154 ********************************************************************/
155 uint16_t test_utilOnesComplementAdd (uint16_t v1, uint16_t v2)
156 {
157 uint32_t result;
159 result = (uint32_t)v1 + (uint32_t)v2;
160 result = (result >> 16) + (result & 0xffff);
161 result = (result >> 16) + (result & 0xffff);
163 return ((uint16_t)result);
164 }
166 /********************************************************************
167 * FUNCTION PURPOSE: Ones complement checksum utility
168 ********************************************************************
169 ********************************************************************/
170 uint16_t test_utilOnesCompChkSum (uint8_t *p, uint32_t nwords)
171 {
172 uint16_t chksum = 0;
173 uint16_t v;
174 uint32_t i;
175 uint32_t j;
177 for (i = j = 0; i < nwords; i++, j+=2) {
178 v = (p[j] << 8) | p[j+1];
179 chksum = test_utilOnesComplementAdd (chksum, v);
180 }
181 return (chksum);
182 } /* utilOnesCompChkSum */
184 /**************************************************************************************
185 * FUNCTION PURPOSE: Compute ipv4 psudo checksum
186 **************************************************************************************
187 * DESCRIPTION: Compute ipv4 psudo checksum
188 **************************************************************************************/
189 uint16_t test_utilGetIpv4PsudoChkSum (uint8_t *data, uint16_t payloadLen)
190 {
191 uint16_t psudo_chksum;
193 psudo_chksum = test_utilOnesCompChkSum (&data[12], 4);
194 psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, (uint16_t) data[9]);
195 psudo_chksum = test_utilOnesComplementAdd(psudo_chksum, payloadLen);
197 return (psudo_chksum);
199 } /* utilGetIpv4PsudoChkSum */
203 #endif
204 typedef struct stats_t
205 {
206 long itx; //initially generated
207 long itx2;
208 long rx;
209 long tx;
210 long n_bad;
211 long n_new;
212 long n_class0_rx; //count of pkts classified
213 long n_class1_rx; //count of pkts classified
214 long n_class2_rx; //count of pkts classified
215 long n_t1;
216 long n_t2;
217 long n_t3;
218 long sec_tx;
219 long sec_rx;
220 long sb_tx;
221 long sb_rx;
222 long secp_rx;
223 long n_auth_ok;
224 } STATS_T;
226 typedef struct head_t
227 {
228 long ip[5];
229 long udp[2];
230 } HEAD_T;
232 typedef struct key_t
233 {
234 long src_ip;
235 long dst_ip;
236 short src_port;
237 short dst_port;
238 } KEY_T;
240 unsigned char mac0[]={0x00,0x01,0x02,0x03,0x04,0x05}; //interface 0
241 unsigned char mac1[]={0x00,0x01,0x02,0x03,0x04,0x06}; //interface 1
242 nwalIpAddr_t OurIp0={ 10, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
243 nwalIpAddr_t OurIp1={ 10, 0, 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
244 nwalIpAddr_t OurIp2={ 10, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
245 nwalIpAddr_t OurIp4IPSEC={ 192,168 , 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
246 nwalIpAddr_t TheirIp4IPSEC={ 192,168 , 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
249 #if 1 //goes with real tx (to laptop)
250 unsigned char real_mac_header[]={0xd4,0xbe,0xd9,0x00,0xd3,0x7e,
251 0x00,0x01,0x02,0x03,0x04,0x05,
252 0x08,0x00};
253 unsigned char real_ip_addr[]={0xa,0x00,0x00,0x64,0xa,0x0,0x0,0xa};
254 #endif
256 #if 0 //goes with loopback
257 unsigned char mac_header[]={0x00,0x01,0x02,0x03,0x04,0x05,
258 0x00,0x11,0x22,0x33,0x44,0x55,
259 0x08,0x00};
260 #endif
261 #define NE 65536
262 HEAD_T *nat;
264 #define NP 5000
265 int n_pkt = NP;
266 STATS_T stats;
268 Trie * P_trie;
269 HEAD_T pkts[NP];
270 #define PERSLOW 10 //% of pkts that will not be fastpath'd
271 int perslow= PERSLOW;
273 /*******************************************
274 *************NETAPI OBJECTS***************
275 *****************************************/
276 static NETAPI_CFG_T our_netapi_default_cfg=
277 {
278 TUNE_NETAPI_PERM_MEM_SZ,
279 128, //start of packet offset for hw to place data on rx for default flow
280 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
281 TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use
282 TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap
283 64, //#descriptors w/o buffers in default heap
284 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128, //size of buffers in default heap
285 128 , //tail room
286 256 //extra room
287 };
289 Pktlib_HeapHandle OurHeap;
290 Pktlib_HeapHandle specialSmall;
291 Pktlib_HeapHandle specialLarge;
293 PKTIO_HANDLE_T *our_chan;
294 PKTIO_HANDLE_T *netcp_rx_chan;
295 PKTIO_HANDLE_T *netcp_rx_chan2;
296 PKTIO_HANDLE_T *netcp_tx_chan;
297 PKTIO_HANDLE_T *netcp_sb_tx_chan;
298 PKTIO_HANDLE_T *netcp_sb_rx_chan;
299 PKTIO_CFG_T our_chan_cfg={PKTIO_RW, PKTIO_LOCAL, PKTIO_Q_ANY, 8};
300 PKTIO_CFG_T netcp_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
301 PKTIO_CFG_T netcp_rx_cfg2={PKTIO_R, (PKTIO_GLOBAL|PKTIO_PKT), PKTIO_Q_ANY, 8};
302 PKTIO_CFG_T netcp_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
303 PKTIO_CFG_T netcp_sb_rx_cfg={PKTIO_R, PKTIO_NA, PKTIO_NA, 8};
304 PKTIO_CFG_T netcp_sb_tx_cfg={PKTIO_W, PKTIO_NA, PKTIO_NA, 8};
306 void house(NETAPI_SCHED_HANDLE_T *s);
307 NETAPI_T netapi_handle;
308 NETAPI_SCHED_HANDLE_T * our_sched;
309 NETAPI_SCHED_CONFIG_T our_sched_cfg={
310 NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 50000 //every 5000 poll loops
311 };
312 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats);
313 NETAPI_TIMER_GROUP_HANDLE_T ourTimerBlock;
314 NETAPI_TIMER_T t1;
315 NETAPI_TIMER_T t2;
316 NETAPI_TIMER_T t3;
318 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
319 int n_fired, //# timers fired
320 NETAPI_TIMER_LIST_T fired_list,
321 uint64_t currentTime);
323 NETCP_CFG_IP_T ip_rule0;
324 NETCP_CFG_IP_T ip_rule1;
325 NETCP_CFG_CLASS_T class_0;
326 NETCP_CFG_CLASS_T class_1;
327 NETCP_CFG_CLASS_T class_2;
328 NETCP_CFG_FLOW_HANDLE_T specialFlow;
330 NETCP_CFG_CLASSIFIER_T class_0_cfg=
331 {
332 NETCP_CFG_CLASS_TYPE_L4,
333 {
334 {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2500}}
335 }
336 };
338 NETCP_CFG_CLASSIFIER_T class_1_cfg=
339 {
340 NETCP_CFG_CLASS_TYPE_L4,
341 {
342 {0,0, NWAL_APP_PLOAD_PROTO_UDP, {2502}}
343 }
344 };
346 NETCP_CFG_ROUTE_T class2_route=
347 {
348 NULL, NULL //* to be filled in
349 };
350 NETCP_CFG_CLASSIFIER_T class_2_cfg=
351 {
352 NETCP_CFG_CLASS_TYPE_L3_L4,
353 {
354 {0, 4 ,0/*fill in below*/ , NULL, NULL, //L2/L3
355 NWAL_APP_PLOAD_PROTO_UDP, {2504}} //L4
356 }
357 };
359 PKTIO_CONTROL_T zap_channel_control={PKTIO_CLEAR, NULL};
361 /* security objects. (for loopback mode) */
362 NETCP_CFG_SA_T rx_tunnel;
363 NETCP_CFG_SA_T tx_tunnel;
364 NETCP_CFG_IPSEC_POLICY_T rx_policy;
365 void * rx_data_mode_handle;
366 void * tx_data_mode_handle;
367 void * rx_inflow_mode_handle;
368 void * tx_inflow_mode_handle;
369 /* rx */
370 NETAPI_SEC_SA_INFO_T rx_sa=
371 {
372 NWAL_SA_DIR_INBOUND,
373 0x44444444, //spi
374 nwal_IpSecProtoESP, //ESP mode
375 nwal_SA_MODE_TUNNEL, //tunnel mode
376 nwal_IPV4, //v4
377 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (them) -> set below */
378 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (us)-> set below*/
379 64,/* replayWindow */
380 NWAL_SA_AALG_HMAC_SHA1,
381 NWAL_SA_EALG_AES_CBC,
382 0,0 //na
383 };
385 /*tx */
386 NETAPI_SEC_SA_INFO_T tx_sa=
387 {
388 NWAL_SA_DIR_OUTBOUND,
389 0x44444444, //spi
390 nwal_IpSecProtoESP, //ESP mode
391 nwal_SA_MODE_TUNNEL, //tunnel mode
392 nwal_IPV4, //v4
393 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Src IP (us) -> set below */
394 { 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* dst IP (them) -> set below*/
395 64, /* NA replayWindow */
396 NWAL_SA_AALG_HMAC_SHA1,
397 NWAL_SA_EALG_AES_CBC,
398 0,0 //seq no
399 };
401 //since we are doing loopback, the rx key params = tx key params
402 static nwalSecKeyParams_t ourTXKeyParams =
403 {
404 16, /* encKeySize: CTR 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_DES_CBC and 0 bytes Salt*/
405 20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_MD5 */
406 NULL, //set below
407 NULL, //set below
408 };
410 static nwalSecKeyParams_t ourRXKeyParams ={
411 16, /* encKeySize: 16 bytes Encryption Key and 4 bytes Salt : 24 bytes:NWAL_SA_EALG_DES_CBC and 0 bytes Salt*/
412 20, /* macKeySize: 16 bytes NWAL_SA_AALG_HMAC_MD5 */
413 NULL, //set below
414 NULL, //set below
415 };
417 //keys
418 static uint8_t ourAuthKey[36] =
419 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
420 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
421 0x20, 0x21, 0x22, 0x23 };
422 static uint8_t ourEncrKey[36] =
423 {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
424 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
425 0x30, 0x31, 0x32, 0x33 };
428 /*************************END NETAPI OBJECTS***********************/
430 #define START_SRC_IP 0x0a00000a
431 #define DST_IP 0xc0a80001
432 #define NEW_START_SRC_IP 0x9eda000a
433 #define DST_PORT 0x555
434 #define START_SRC_PORT 0x1234
435 #define NEW_START_SRC_PORT 100
436 void update_header(HEAD_T * p_head, int len)
437 {
438 unsigned char *p = (unsigned char *) &p_head->udp[1];
439 len -= (20+14);
440 /* update ip checksum */
441 /* update udp checksum */
442 /* update length */
443 *p= (len&0xff00)>>8;
444 *(p+1) = len&0xff;
445 }
447 #if 0
448 void gen_pkts(int np)
449 {
450 int i;
451 int ip = START_SRC_IP &0xff;
452 int port= START_SRC_PORT;
453 //HEAD_T temp={{0x25000200,0xdead0000,0x80110000,START_SRC_IP,DST_IP},
454 // {START_SRC_PORT<<16|DST_PORT,0x01ec<<16|0x0000}};
455 HEAD_T temp;
456 memcpy(&temp,&testPkt[0],sizeof(HEAD_T));
458 for(i=0;(i<np) && (i<NP);i++)
459 {
460 memcpy(&pkts[i],&temp,sizeof(temp));
461 update_header(&pkts[i],512); /* update checksums etc */
462 /* change template for new pkt */
463 ip+=1;
464 if(ip>254) {(ip=START_SRC_IP&0xff); port+=1; }
465 temp.ip[3] = htonl((START_SRC_IP&0xffffff00)| ip);
466 temp.udp[0] = htonl( (temp.udp[0]&0xffff0000)| port);
467 temp.udp[1] = htonl(temp.udp[1]);
469 }
470 n_pkt=np;
471 }
472 #endif
474 void build_table(Trie * p_trie)
475 {
476 int i;
477 int sport=NEW_START_SRC_PORT;
478 HEAD_T temp,temp2;
479 KEY_T key;
481 memcpy(&temp,&testPkt[14],sizeof(temp));
483 //insert entry into trie
484 key.src_ip = temp.ip[3];
485 key.dst_ip = temp.ip[4];
486 key.src_port= (temp.udp[0]&0xffff0000)>>16;
487 key.dst_port= (temp.udp[0]&0x0000ffff);
488 trie_insert(p_trie,(char *)&key,sizeof(key), (void *) &nat[0]); //asociate with nat entry 0
490 //build nat table
491 for(i=0;i<100;i++)
492 {
493 memcpy(&temp2,&testPkt[14],sizeof(temp));
494 temp2.udp[0] = (temp2.udp[0] & 0xffff0000) | sport;
495 memcpy(&nat[i], &temp2, sizeof(temp2));
496 sport+= 1;
497 }
498 }
500 //===========stub transmitter==================
501 void send_pkt(Ti_Pkt *pkt, int len)
502 {
503 //just free pkt. Don't send
504 Pktlib_freePacket((Ti_Pkt*)pkt);
505 return;
506 }
508 //==========stub slow path============
509 void slow_path(Ti_Pkt *pkt, int len)
510 {
511 // debug: check descriptor for validity by verifying that desciptor link field is null as expected\n");
512 {Ti_Pkt * k= Pktlib_getNextPacket(pkt); if(k != 0) {printf(" slowpath, nexpkt != NULL");}}
513 //just free pkt
514 Pktlib_freePacket((Ti_Pkt*)pkt);
515 return;
516 }
517 /* check header */
518 struct LastPktInfo
519 {
520 int iface;
521 int ipcsum;
522 int l4csum;
523 } ;
524 static struct LastPktInfo lpInfo;
526 int check_header(HEAD_T * p_head, PKTIO_METADATA_T * p_meta)
527 {
528 if (NWAL_RX_FLAG1_META_DATA_VALID & p_meta->u.rx_meta->rxFlag1)
529 {
530 lpInfo.iface = ((unsigned int)p_meta->u.rx_meta->appId) &0xff; //last byte is interface num
531 lpInfo.ipcsum =(p_meta->u.rx_meta->rxFlag1 & NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_MASK )== NWAL_RX_FLAG1_IPV4_CHKSUM_VERIFY_ACK ? 1 : 0;
532 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;
533 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC)
534 {
535 stats.sec_rx++;
536 }
537 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_IPSEC_POLICY)
538 {
539 stats.secp_rx++;
540 }
542 if ((unsigned int)p_meta->u.rx_meta->appId & NETAPI_NETCP_MATCH_CLASS)
543 {
544 int c= ((unsigned int)p_meta->u.rx_meta->appId >>8)&0xffff;
545 if (c==0) stats.n_class0_rx +=1;
546 else if (c==1) stats.n_class1_rx +=1;
547 else if (c==2) stats.n_class2_rx +=1;
548 else printf("**NET_TEST RX -unknown class: %x\n", p_meta->u.rx_meta->appId);
549 }
550 }
552 return 1;
553 }
555 #define PKT_LEN 1400
556 void test_alloc_free(int n)
557 {
558 int i;
559 Ti_Pkt * b;
561 for(i=0;i<n;i++)
562 {
563 b=Pktlib_allocPacket(OurHeap,PKT_LEN);
564 Pktlib_freePacket(b);
565 }
566 }
568 //measurement test points
569 unsigned int vv1;
570 unsigned int vv2;
571 unsigned int vv3;
572 unsigned int vv4;
573 unsigned int vv5;
574 unsigned int vv6;
575 //these are updated by pktio.
576 unsigned int vv7p;
577 unsigned int vv8p;
578 unsigned int vv9p;
579 unsigned int vv10p;
580 unsigned int vv11p;
581 unsigned int vv12p;
583 unsigned int vv11;
585 unsigned int vv13p; //rcv path
586 unsigned int vv14p;
587 unsigned int vv15p;
589 extern unsigned int nwal_prof1,nwal_prof2,nwal_prof3,nwal_prof4,nwal_prof5,nwal_prof6;
591 //#define REASSEMBLE_BENCH
592 #ifdef REASSEMBLE_BENCH
593 #include <ti/drv/pa/example/reassemLib/reassemLib.h>
594 /*--------------reassembly benchmark--------------------------------*/
595 void our_reassemble_bench(int nfrags)
596 {
597 paIPReassemblyConfig_t Config={5,128,10000 };
598 int i,j;
599 int len;
600 Ti_Pkt tip;
601 char *buffer;
602 unsigned long v1;
603 unsigned long v2;
604 unsigned long sum1=0;
605 unsigned long sum2=0;
606 paEx_reassemLibInit(&Config);
607 for(j=0;j<200/nfrags;j++)
608 {
609 for(i=0;i<nfrags;i++)
610 {
611 short temp;
612 tip=Pktlib_allocPacket(OurHeap,PKT_LEN);
613 Pktlib_getDataBuffer(tip,(uint8_t**)&buffer,&len);
614 memcpy(&buffer[0],&testPkt[14],20); //IP header
615 if (i < (nfrags-1)) buffer[6] = 0x20;
616 temp = i*40;
617 buffer[6]|= (temp&0x1f00)>>8;
618 buffer[7]= (temp&0xff);
619 temp = 20+40*8;
620 buffer[2]= (temp&0xff00)>>8;
621 buffer[3]= (temp&0xff);
622 Pktlib_setPacketLen(tip, temp);
623 v1= netapi_timing_stop();
624 paEx_reassemLibProc(tip, 0xffff);
625 v2= netapi_timing_stop();
626 sum1+= v2-v1;
627 }
628 sum2 += v2-v1;
629 }
630 printf("reasssembly test: %d trials, %d frags/pkt %d cycles/frag %d cycles/last frag\n",j,nfrags, sum1/(j*nfrags), sum2/(j));
631 }
632 #endif
634 /*--------------basic pktio send/recv benchmark----------------------*/
635 unsigned int timings[10];
636 void our_pktio_bench(int ntrials)
637 {
638 int i;
639 #define NBATCH 8
640 Ti_Pkt tip;
641 unsigned char * pData;
642 int len;
643 int n;
644 int err;
645 int sum =0;
647 Osal_cache_op_measure_reset();
648 for(i=0;i<10;i++) timings[i]=0;
649 printf("calibration loop .. ");
650 for(i=0;i<1000;i++)
651 {
652 vv1= netapi_timing_stop();
653 vv2= netapi_timing_stop();
654 sum+=(vv2-vv1);
655 }
656 printf(" accuracy = +- %d cycles\n", sum/1000);
657 sleep(1);
659 PKTIO_METADATA_T meta[10]={0};
660 //send single, recv single
661 for(i=0;i<ntrials;i++)
662 {
663 vv1= netapi_timing_stop();
664 tip=Pktlib_allocPacket(OurHeap,PKT_LEN);
665 vv2= netapi_timing_stop();
666 Pktlib_getDataBuffer(tip,&pData,&len);
667 vv3= netapi_timing_stop();
668 pktio_send(our_chan,tip,&meta[0],&err);
669 vv4= netapi_timing_stop();
670 n=pktio_poll(our_chan,NULL , &err);
671 vv5= netapi_timing_stop();
672 timings[0]+=(vv6-vv4);
673 timings[1]+=(vv5-vv4);
674 timings[2]+=(vv7p-vv4);
675 timings[3]+=(vv4-vv3);
676 timings[4]+=(vv8p-vv3);
677 timings[5]+=(vv3-vv1);
678 timings[6]+=(vv9p-vv8p);
679 timings[7]+=(vv10p-vv7p);
680 timings[8]+=(vv11-vv6);
681 }
682 printf("pktio bench. rx=%d (wcb%d) (toqm%d) tx=%d (toqm%d) alloc=%d qpush=%d qpop=%d free=%d\n", timings[0]/ntrials,
683 timings[1]/ntrials, timings[2]/ntrials,timings[3]/ntrials, timings[4]/ntrials,timings[5]/ntrials,
684 timings[6]/ntrials,timings[7]/ntrials, timings[8]/ntrials );
685 printf("raw qpop = %d raw qpush = %d pa2va = %d ", pktio_get_qop_time(),
686 pktio_get_qpush_time(),
687 pktio_get_pa2va_time());
688 {
689 unsigned int ccycles;
690 int n_c_ops;
691 ccycles =Osal_cache_op_measure(&n_c_ops);
692 printf("n_c_ops=%d cache_op_time=%d (total) = %d (pp)\n", n_c_ops, ccycles, n_c_ops? (ccycles/(n_c_ops)) : 0);
693 }
695 }
696 /*-----------test driver: gen an input pkt------- */
697 //char buffer[sizeof(HEAD_T)+PKT_LEN];
698 Ti_Pkt * get_pkt(int n, unsigned int *p_len)
699 {
700 int ind;
701 long long temp;
702 Ti_Pkt * b;
703 char * buffer;
704 unsigned int len;
706 if (pktloopback==0)
707 {
708 if (n>=TX_BURST) return NULL; //just gen pkts to warm swtich, so that it knows
709 //our mac is valid
710 }
711 b=Pktlib_allocPacket(OurHeap,PKT_LEN);
712 if (!b)
713 {printf("net_test: get_pkt() heap empty!! %d pkts gen'd %d \n", n); return NULL;};
715 //debug - way to validate descriptor
716 {Ti_Pkt* k= Pktlib_getNextPacket(b);
717 if(k != 0) {printf(" genpkt, nexpkt != NULL");}}
720 //get pointer to buffer area of packet
721 Pktlib_getDataBuffer(b,(uint8_t**)&buffer,&len);
722 if (!buffer)
723 {printf("net_test: get_pkt() heap returned empty buffer %d \n", n); return NULL;};
725 #if 0
726 if (pktloopback==0)
727 {
728 temp = (long long) rand();
729 temp *= PKT_LEN;
730 temp /= RAND_MAX;
731 temp +=2;
732 *p_len = (int) temp;
733 *p_len = *p_len &0xfffffffe;
734 temp = (long long) rand();
735 temp *= n_pkt;
736 temp /= RAND_MAX;
737 ind = (int) temp;
738 update_header(&pkts[ind],*p_len);
739 //printf("get pkt:%d %d ind=%d len=%d\n",RAND_MAX, rand(),ind, *p_len);
740 memcpy(&buffer[0], &mac_header[0],14);
741 memcpy(&buffer[14],(char*)&pkts[ind],sizeof(HEAD_T));
742 }
743 else
744 #endif
746 //copy test packet into buffer
747 {
748 memcpy(&buffer[0], &testPkt[0],TEST_PKT_LEN);
749 *p_len = TEST_PKT_LEN;
750 }
751 return b;
752 }
755 /*--------------------------------------------------------------
756 *----------utility to flip a packet and send
757 *--------------------back to source----------------------------
758 * flag=1 => ipsec
759 *--------------------------------------------------------------*/
760 void flip_and_send_pkt(Ti_Pkt *tip, unsigned char * p_pkt, int len, int flag)
761 {
762 unsigned char mac_temp[6];
763 unsigned char ip_temp[4];
764 unsigned char new_dest_port[2]={0x75,0x30}; // 30000
765 uint16_t blah;
766 //mac
767 memcpy(&mac_temp,&p_pkt[0],6);
768 memcpy(&p_pkt[0],&p_pkt[6],6);
769 memcpy(&p_pkt[6],&mac_temp,6);
770 //memcpy(&p_pkt[0],real_mac_header,6); //for testing to wireshark pc
772 //ip (outer in case of ipsec)
773 memcpy(&ip_temp, &p_pkt[14+12],4);
774 memcpy(&p_pkt[14+12],&p_pkt[14+12+4],4);
775 memcpy(&p_pkt[14+12+4],&ip_temp,4);
777 //outer checksum to 0
778 if (!flag) memset(&p_pkt[14+10],0,2);
780 //inner ip &udp for ipsec
781 if (flag)
782 {
783 //just drop non-udp packet
784 if (p_pkt[14+20+8+16+9]!=0x11)
785 {
786 stats.n_new+=1;Pktlib_freePacket(tip); return;
787 }
789 //spi
790 //memset(&p_pkt[14+20],0x88,4);
791 //inner ip
792 memcpy(&ip_temp, &p_pkt[14+20+8+16+12],4);
793 memcpy(&p_pkt[14+20+8+16+12],&p_pkt[14+20+8+16+12+4],4);
794 memcpy(&p_pkt[14+20+8+16+12+4],&ip_temp,4);
796 //udp
797 memcpy(&p_pkt[14+20+8+16+20+2],&new_dest_port[0],2);
798 memset(&p_pkt[14+20+8+16+20+6],0,2); //checksum
800 #ifdef IPSEC_MODE_TX_SIDEBAND
802 //inner ip checksum : leave alone
803 #if 0
804 blah=test_utilOnesCompChkSum (&p_pkt[14+20+8+16], 10);
805 p_pkt[14+20+8+16+10]= (blah&0xff00)>>8;
806 p_pkt[14+20+8+16+11]= blah&0xff;
807 #endif
809 //tbd udp checksum (leave at 0)
811 //outer ip, set to 0 (we will compute on way out
812 memset(&p_pkt[14+10],0,2);
814 #else //inflow, don't touch outer , clear inner
815 memset(&p_pkt[14+20+8+16+10],0,2); //inner checksum, we will compute on way out
816 //outer ip checksum : leave alone
817 #if 0
818 blah = test_utilOnesCompChkSum (&p_pkt[14], 10);
819 p_pkt[14+10]= (blah&0xff00)>>8;
820 p_pkt[14+11]= blah&0xff;
821 #endif
822 #endif
823 }
824 else
825 {
826 memset(&p_pkt[14+20+6],0,2);//0 udp checksum (we will compute on way out
827 memcpy(&p_pkt[14+20+2],&new_dest_port[0],2);
828 }
830 //IPSEC case,
831 if (flag)
832 {
833 #ifdef IPSEC_MODE_TX_SIDEBAND
834 //send to crypto for encryption
835 //12 byte auth tag
836 {
837 PKTIO_METADATA_T meta = {PKTIO_META_SB_TX,{0},0};
838 int err;
839 nwalDmTxPayloadInfo_t meta_tx={0};
840 meta.sa_handle=tx_data_mode_handle; //use TX SA context
841 meta_tx.ploadLen = len;
842 meta_tx.encOffset = 14+20+8+16 ;
843 meta_tx.authOffset =14+20 ;
844 meta_tx.encSize=len - 14- 20-8-16-12;
845 meta_tx.authSize= len -14-20-12;
846 meta_tx.encIvSize=16;
847 meta_tx.pEncIV= &p_pkt[14+20+8]; //just use same IV..
848 meta_tx.authIvSize=0;
849 meta_tx.pAuthIV=NULL;
850 meta_tx.aadSize=0;
851 meta_tx.pAad=NULL;
852 /* post it to netcp sb tx channel*/
853 meta.u.tx_sb_meta=&meta_tx;
854 pktio_send(netcp_sb_tx_chan,tip,&meta,&err);
855 }
857 #else
858 {
859 //inflow tx
860 //send pkt directly, asking for IP and UDP checksum offloads AND IPSEC to be applied
861 PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
862 int err;
863 nwalTxPktInfo_t meta_tx={0};
864 meta.sa_handle=tx_inflow_mode_handle; //this tells netapi that inflow crypto needs to be applied
865 meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_DO_IPSEC_CRYPTO| NWAL_TX_FLAG1_META_DATA_VALID );
866 meta_tx.saOffBytes=14+20;
867 meta_tx.saPayloadLen=len-14-20; //don't include tag, mac and outer header
868 meta_tx.startOffset = 0;
869 meta_tx.ipOffBytes = 14+20+8+16; //to inner header
870 meta_tx.l4OffBytes = 14+20+8+16+20; //to L4
871 meta_tx.l4HdrLen = 8;
872 meta_tx.ploadLen = (unsigned) ((p_pkt[14+20+8+16+20+4]<<8)|p_pkt[14+20+8+16+20+4+1]) -8 ;
873 meta_tx.pseudoHdrChecksum =
874 test_utilGetIpv4PsudoChkSum(&p_pkt[14+20+8+16],8+ meta_tx.ploadLen);
876 /* post it to netcp tx channel*/
877 meta.u.tx_meta=&meta_tx;
878 pktio_send(netcp_tx_chan,tip,&meta,&err);
879 stats.tx +=1;
880 stats.sec_tx +=1;
881 }
882 #endif
885 }
886 else //non ipsec send pkt directly, asking for IP and UDP checksum ofload
887 {
888 PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
889 int err;
890 nwalTxPktInfo_t meta_tx2={0};
891 meta2.sa_handle=nwal_HANDLE_INVALID;
892 meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM|NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
893 meta_tx2.startOffset = 0;
894 meta_tx2.ipOffBytes = 14;
895 meta_tx2.l4OffBytes = 14+20;
896 meta_tx2.l4HdrLen = 8;
897 meta_tx2.ploadLen = (unsigned) ((p_pkt[14+20+4]<<8)|p_pkt[14+20+4+1]) -8 ;
898 meta_tx2.pseudoHdrChecksum =
899 test_utilGetIpv4PsudoChkSum(&p_pkt[14],8+ meta_tx2.ploadLen);
901 /* post it to netcp tx channel*/
902 meta2.u.tx_meta=&meta_tx2;
903 pktio_send(netcp_tx_chan,tip,&meta2,&err);
904 stats.tx +=1;
905 }
906 }
911 /***************************************
912 benchmark receive handler
913 ****************************************/
914 void recv_cb_bench(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
915 PKTIO_METADATA_T meta[], int n_pkts,
916 uint64_t ts )
917 {
918 int i;
919 vv6= netapi_timing_stop();
920 for (i=0;i<n_pkts; i++)
921 {
922 Pktlib_freePacket(p_recv[i]);
923 }
924 vv11 = netapi_timing_stop();
925 }
927 /****************************************************************************************/
928 /******************SB Accelerator Callback PKT RECEIVE HANDLER *************************/
929 /****************** Handles Decrypt and Encrypt operation callbacks ******************/
930 /******************************************************************************************/
931 void recv_sb_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
932 PKTIO_METADATA_T meta[], int n_pkts,
933 uint64_t ts )
934 {
935 int i;
936 int len;
937 int p;
938 HEAD_T * p_res;
939 Ti_Pkt * tip;
940 unsigned int templen;
941 int err;
942 KEY_T key;
943 char * p_pkt;
944 HEAD_T * p_head;
945 HEAD_T temp_head;
946 int tag_cmp=0;
947 unsigned int hash[3];
949 /* loop over received pkts */
950 for(i=0;i<n_pkts;i++)
951 {
952 tip = p_recv[i];
953 Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
954 len = Pktlib_getPacketLen(tip);//real length
956 //is this a decrypt (rx_tunnel) complete
957 if (meta[i].u.rx_sb_meta->appId == rx_tunnel)
958 {
959 stats.sb_rx+=1;
960 //copy hash out of meta data (for some reason it needs endian conversion)
961 hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
962 hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
963 hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
965 if(stats.sb_rx<=16)
966 {
967 char *tp = (char *) &hash[0];
968 dump_header((long*)p_pkt, stats.sb_rx, meta[i].u.rx_sb_meta->appId,0);
969 printf("tag in pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",
970 p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
971 p_pkt[len-7],p_pkt[len-6],
972 p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);
973 printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",
974 tp[0],tp[1],tp[2],tp[3],tp[4],tp[5],
975 tp[6],tp[7],tp[8],tp[9],tp[10],tp[11]);
976 }
977 //check tag
978 tag_cmp = memcmp(&p_pkt[len-12],(char*) &hash[0],12); //todo, really use meta->authTagLen
979 stats.n_auth_ok += !(tag_cmp);
980 flip_and_send_pkt(tip, p_pkt, len,1); //flip packet to echo back and send
981 }
982 //this is an encrypt (tx tunnel) complete
983 else if(meta[i].u.rx_sb_meta->appId== tx_tunnel )
984 {
985 hash[0]= htonl( meta[i].u.rx_sb_meta->pAuthTag[0]);
986 hash[1]= htonl( meta[i].u.rx_sb_meta->pAuthTag[1]);
987 hash[2]= htonl( meta[i].u.rx_sb_meta->pAuthTag[2]);
988 stats.sb_tx+=1;
989 if(stats.sb_tx<=16)
990 {
991 char *tp1 = (char *) &hash[0];
992 dump_header((long*)p_pkt, stats.sb_tx, meta[i].u.rx_sb_meta->appId,0);
993 printf("tag in original rx pkt=%x %x %x %x %x %x %x %x %x %x %x %x\n",
994 p_pkt[len-12],p_pkt[len-11],p_pkt[len-10],p_pkt[len-9], p_pkt[len-8],
995 p_pkt[len-7],p_pkt[len-6],
996 p_pkt[len-5],p_pkt[len-4],p_pkt[len-3],p_pkt[len-2],p_pkt[len-1]);
998 printf("tag from SA=%x %x %x %x %x %x %x %x %x %x %x %x\n",
999 tp1[0],tp1[1],tp1[2],tp1[3],tp1[4],tp1[5],
1000 tp1[6],tp1[7],tp1[8],tp1[9],tp1[10],tp1[11]);
1001 }
1002 //put the computed tag in the packet
1003 memcpy(&p_pkt[len-12],(char*)&hash[0],12); //todo, really use meta->authTagLen
1004 {
1005 PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
1006 nwalTxPktInfo_t meta_tx={0};
1007 // now send directly
1008 meta2.sa_handle=nwal_HANDLE_INVALID;
1009 meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);//only outer IP header checksum. no udp checksum possible since pkt is already encrypted
1010 meta_tx.startOffset = 0;
1011 meta_tx.ipOffBytes = 14;
1012 //not used
1013 meta_tx.l4OffBytes = 0;
1014 meta_tx.l4HdrLen = 0;
1015 meta_tx.ploadLen = 0;
1017 /* post it to netcp tx channel*/
1018 meta2.u.tx_meta=&meta_tx;
1019 pktio_send(netcp_tx_chan,tip,&meta2,&err);
1020 stats.tx +=1;
1021 }
1022 }
1023 else printf("netapi recv_sb_cb: unknown appiD %x \n",meta[i].u.rx_sb_meta->appId );
1024 }
1025 }
1027 /******************************************************/
1028 /******************PKT RECEIVE HANDLER *************************/
1029 /******************************************************/
1030 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
1031 PKTIO_METADATA_T meta[], int n_pkts,
1032 uint64_t ts )
1033 {
1034 int i;
1035 int len;
1036 int p;
1037 HEAD_T * p_res;
1038 Ti_Pkt * tip;
1039 unsigned int templen;
1040 int err;
1041 KEY_T key;
1042 char * p_pkt;
1043 HEAD_T * p_head;
1044 HEAD_T temp_head;
1046 p_head=&temp_head;
1048 //debug
1049 #if 0
1050 if (n_pkts != TX_BURST) {
1051 printf("recv_cb, txsofar=%d rxsofar=%d np = %d, NOT %d\n",
1052 stats.itx, stats.rx, n_pkts,TX_BURST);
1053 our_stats_cb(netapi_handle,NULL);
1054 }
1055 #endif
1056 //test_alloc_free(7);
1057 //printf("recv start\n");
1059 /* loop over received pkts */
1060 for(i=0;i<n_pkts;i++)
1061 {
1062 tip = p_recv[i];
1063 Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
1064 len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
1066 //debug: validate descriptor */
1067 if(Pktlib_getNextPacket(tip) != 0) {printf(" rcv_cb, nexpkt != NULL");}
1068 //debug printf("recv pkt, len=%d %d\n", len, templen);
1069 stats.rx+=1;
1071 #ifdef DEBUG_DESC
1072 if (stats.rx<16){printf(">rx dmp.."); dump_descr((long *) tip, stats.rx);}
1073 else if (stats.rx>99) {printf(">rx dmp.."); dump_descr((long *) tip,stats.rx);}
1074 #endif
1075 if(stats.rx<=16)
1076 {
1077 dump_header((long*)p_pkt, stats.rx, meta[i].u.rx_meta->appId,meta[i].u.rx_meta->rxFlag1);
1078 }
1079 /* check header */
1080 memcpy(p_head,&p_pkt[14],sizeof(HEAD_T));
1082 if ((p_head->ip[2]&0x0000ff00)==0x00003200)
1083 {
1084 if (!check_header(p_head,&meta[i])) {
1085 stats.n_bad+=1;Pktlib_freePacket(tip); continue;
1086 }
1088 //process IP SEC PACKET
1089 #ifdef IPSEC_MODE_RX_SIDEBAND
1090 {
1091 //ship to crypto for decrypt!!
1092 //12 byte auth tag
1093 PKTIO_METADATA_T meta2 = {PKTIO_META_SB_TX,{0},0};
1094 nwalDmTxPayloadInfo_t meta_tx={0};
1095 meta2.sa_handle=rx_data_mode_handle;
1096 meta_tx.ploadLen = len;
1097 meta_tx.encOffset = 14+20+8+16 ;
1098 meta_tx.authOffset =14+20 ;
1099 meta_tx.encSize=len - 14- 20-8-16-12;
1100 meta_tx.authSize= len -14-20-12;
1101 meta_tx.encIvSize=16;
1102 meta_tx.pEncIV= &p_pkt[14+20+8];
1103 meta_tx.authIvSize=0;
1104 meta_tx.pAuthIV=NULL;
1105 meta_tx.aadSize=0;
1106 meta_tx.pAad=NULL;
1107 /* post it to netcp sb tx channel*/
1108 meta2.u.tx_sb_meta=&meta_tx;
1109 pktio_send(netcp_sb_tx_chan,tip,&meta2,&err);
1110 continue;
1111 }
1112 #else
1113 //inflow mode. flip and send
1114 flip_and_send_pkt(tip,p_pkt,len,1);
1115 #endif
1116 }
1117 else if ((p_head->ip[2]&0x0000ff00)!=0x00001100)
1118 {
1119 stats.n_new+=1;Pktlib_freePacket(tip); continue;
1120 }
1121 else //non ipsec
1122 {
1123 if (!check_header(p_head,&meta[i])) {
1124 stats.n_bad+=1;Pktlib_freePacket(tip); continue;
1125 }
1127 #if 0
1128 /* lookup flow */
1129 key.src_ip = p_head->ip[3];
1130 key.dst_ip = p_head->ip[4];
1131 key.src_port= (p_head->udp[0]&0xffff0000)>>16;
1132 key.dst_port= (p_head->udp[0]&0x0000ffff);
1133 p_res= (HEAD_T *) trie_lookup(P_trie, (char *) &key, sizeof(key));
1134 if (!p_res) { stats.n_new+=1; slow_path(tip, len); continue;}
1136 /* copy header */
1137 memcpy((char *) p_head, (char *) p_res, sizeof(HEAD_T));
1139 memcpy(&p_pkt[14],p_head,sizeof(HEAD_T));
1140 /* update_mac(&p_pkt[0]); */
1142 /* 'simulate' send pkt */
1143 send_pkt(tip,len);
1144 #endif
1145 //just flip and send
1146 flip_and_send_pkt(tip,p_pkt,len,0);
1147 }
1148 }
1149 //printf("recv done\n");
1150 }
1152 //timer callback
1153 void our_timer_cb( NETAPI_TIMER_GROUP_HANDLE_T th,
1154 int n_fired, //# timers fired
1155 NETAPI_TIMER_LIST_T fired_list,
1156 uint64_t currentTime)
1157 {
1158 int i;
1159 NETAPI_TIMER_T tx;
1160 int cookie;
1161 int err;
1162 unsigned long long et;
1163 //DEBUGprintf("TIMER CALLBACK @ %lld %d timers\n", currentTime, n_fired);
1164 tx = netapi_TimerGetFirst(fired_list);
1165 for(i=0;i<n_fired;i++)
1166 {
1167 cookie = (int) netapi_TimerGetCookie(tx);
1168 et = netapi_TimerGetTs(tx); //debug
1169 //DEBUGprintf(" timer %d - cookie = %d expected ts=%lld (delta=%lld)\n", i, cookie, et, currentTime-et);
1170 if (cookie ==1)
1171 {
1172 stats.n_t1+=1;
1173 t1 = netapi_TimerGroupStartTimer(
1174 th,
1175 (void *) 1,
1176 100LL, //timer group tics
1177 &err);
1178 }
1179 else if (cookie ==2)
1180 {
1181 stats.n_t2+=1;
1182 t2 = netapi_TimerGroupStartTimer(
1183 th,
1184 (void *) 2,
1185 200LL, //timer group ticks
1186 &err);
1187 }
1188 else
1189 {
1190 stats.n_t3+=1;
1191 t3 = netapi_TimerGroupStartTimer(
1192 th,
1193 (void *) 3,
1194 300LL, //timer group ticks
1195 &err);
1196 //cancel 1 and restart 1
1197 netapi_TimerGroupCancel(th,t1,&err);
1198 t1 = netapi_TimerGroupStartTimer(
1199 th,
1200 (void *) 1,
1201 100LL, //timer group ticks
1202 &err);
1203 }
1204 tx = netapi_TimerGetNext(fired_list,tx);
1205 }
1206 }
1209 static int np2process = NP;
1210 /******************************************************
1211 * stats callback
1212 *******************************************************/
1213 void our_stats_cb(NETAPI_T h, paSysStats_t* pPaStats)
1214 {
1215 uint32_t numFreeDataPackets;
1216 uint32_t numZeroBufferPackets;
1217 uint32_t numPacketsinGarbage;
1218 Pktlib_HeapStats pktLibHeapStats;
1220 printf(">*****stats @ %lld\n", netapi_getTimestamp());
1221 //printf("netcp_tx_handle check %x\n", netcp_tx_chan->back);
1222 printf(">itx=%d rx=%d tx=%d bad=%d slow=%d \n>rx_class0=%d rx_class1=%d rx_class2=%d secRx=%d secPRX=%d sb_rx=%d sb_tx=%d auth_ok=%d\n n_t1=%d n_t2=%d n_t3=%d\n",stats.itx, stats.rx, stats.tx, stats.n_bad, stats.n_new,
1223 stats.n_class0_rx, stats.n_class1_rx,
1224 stats.n_class2_rx, stats.sec_rx, stats.secp_rx, stats.sb_rx, stats.sb_tx, stats.n_auth_ok,
1225 stats.n_t1, stats.n_t2,stats.n_t3);
1227 if(pPaStats)
1228 {
1229 printf("C1 number of packets: %d\n", pPaStats->classify1.nPackets);
1230 printf("C1 number IPv4 packets: %d\n", pPaStats->classify1.nIpv4Packets);
1231 //printf("C1 number llc/snap fail: %d\n", pPaStats->classify1.nLlcSnapFail);
1232 printf("C1 number table matched: %d\n", pPaStats->classify1.nTableMatch);
1233 printf("C1 number failed table matched: %d\n", pPaStats->classify1.nNoTableMatch);
1234 printf ("C1 number of parse fail: %d\n",pPaStats->classify1.nParseFail);
1235 printf("C1 number of command failures: %d\n", pPaStats->classify1.nCommandFail);
1236 printf("C1 number invalid reply dests: %d\n", pPaStats->classify1.nInvalidComReplyDest);
1237 printf ("C1 number of silent discard: %d\n",pPaStats->classify1.nSilentDiscard);
1238 printf("C1 number of invalid control: %d\n", pPaStats->classify1.nInvalidControl);
1239 printf ("C1 number of invalid states: %d\n",pPaStats->classify1.nInvalidState);
1240 printf ("C1 number of system fails: %d\n",pPaStats->classify1.nSystemFail);
1241 printf ("C2 number parse failed : %d\n",pPaStats->classify2.nParseFail);
1242 printf ("C2 number Invld Header : %d\n",pPaStats->classify2.nInvldHdr);
1243 printf ("C2 number udp : %d\n",pPaStats->classify2.nUdp);
1244 printf ("C2 number tcp : %d\n",pPaStats->classify2.nTcp);
1245 printf ("C2 number cmd fail : %d\n",pPaStats->classify2.nCommandFail);
1246 printf ("C2 number silent drop : %d\n",pPaStats->classify2.nSilentDiscard);
1247 printf ("C2 number invalid cntrl : %d\n\n",pPaStats->classify2.nInvalidControl);
1248 }
1249 Pktlib_getHeapStats(OurHeap, &pktLibHeapStats);
1250 printf("main heap stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
1251 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
1252 printf(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
1253 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
1254 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
1256 Pktlib_getHeapStats(specialSmall, &pktLibHeapStats);
1257 printf("specialSmall heap stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
1258 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
1259 printf(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
1260 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
1261 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
1264 Pktlib_getHeapStats(specialLarge, &pktLibHeapStats);
1265 printf("specialLarge heap stats> #free=%d #zb=%d #garbage=%d\n", pktLibHeapStats.numFreeDataPackets,
1266 pktLibHeapStats.numZeroBufferPackets, pktLibHeapStats.numPacketsinGarbage);
1267 printf(" > #dataBufThreshStatus=%d #dataBufStarvCounter=%d #zBufThreshStatus=%d #zBufStarvCounter=%d \n",
1268 pktLibHeapStats.dataBufferThresholdStatus,pktLibHeapStats.dataBufferStarvationCounter,
1269 pktLibHeapStats.zeroDataBufferThresholdStatus, pktLibHeapStats.zeroDataBufferStarvationCounter);
1272 //debug = dump timer polling stats
1273 dump_poll_stats();
1276 }
1278 //******************************************************
1279 //use scheduling housekeeping callback to generate pkts
1280 //******************************************************
1281 void house(NETAPI_SCHED_HANDLE_T * s)
1282 {
1283 Ti_Pkt * tip;
1284 unsigned int len;
1285 nwalTxPktInfo_t meta_tx;
1286 PKTIO_METADATA_T meta = {PKTIO_META_TX,{0},0};
1287 int err;
1288 static int house_pkts_gened=0;
1289 int p;
1290 unsigned char * pIpHdr,* pData;
1291 unsigned int vv1,vv2,vv3;
1292 unsigned int sum_vv1=0;
1293 unsigned int sum_vv2=0;
1294 unsigned int sum_vv3=0;
1295 unsigned int sum_vv4=0;
1296 unsigned int sum_vv5=0;
1298 unsigned int nwal_flow_vv1,nwal_flow_vv2;
1299 unsigned int nwal_sum_vv1=0;
1300 unsigned int nwal_sum_vv2=0;
1301 unsigned int nwal_sum_vv3=0;
1302 unsigned int nwal_sum_vv4=0;
1303 unsigned int nwal_sum_vv5=0;
1304 unsigned int nwal_sum_vv6=0;
1306 unsigned int nwal_sum_flow_vv1=0;
1307 unsigned int nwal_sum_flow_vv2=0;
1308 static int first =0;
1309 Cppi_HostDesc* pPktDesc;
1311 Osal_cache_op_measure_reset();
1312 memset(&meta_tx,0,sizeof(meta_tx));
1313 for(p=0;p<TX_BURST;p++) {
1314 //reguest stats
1315 if ((house_pkts_gened>0) && (! (house_pkts_gened%1000)) )
1316 {
1317 printf("net_test> request stats at n=%d \n",house_pkts_gened);
1318 netcp_cfgReqStats(netapi_handle, our_stats_cb, 0,&err);
1319 if (err!=0) {printf("stats req failed\n");}
1320 }
1323 if (house_pkts_gened >= np2process+ 100)
1324 {
1325 //shutdown
1326 netapi_schedShutdown(s,NULL,&err);
1327 continue;
1328 }
1330 else if (house_pkts_gened >= np2process) { house_pkts_gened+=1; continue;}
1333 /* manufacture a pkt to transmit */
1334 tip = get_pkt(house_pkts_gened, &len);
1335 if(!tip) { house_pkts_gened +=1; continue; }
1338 /* set the pkt length */
1339 vv1 = netapi_timing_start();
1340 Pktlib_setPacketLen(tip, len);
1342 /* set up meta data */
1343 meta.sa_handle=nwal_HANDLE_INVALID;
1344 meta_tx.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_DO_UDP_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID);
1345 meta_tx.startOffset = 0;
1346 //GONE in V2 meta_tx.pktLen = len;
1347 meta_tx.ipOffBytes = TEST_PKT_IP_OFFSET_BYTES;
1348 meta_tx.l4OffBytes = TEST_PKT_UDP_OFFSET_BYTES;
1349 meta_tx.l4HdrLen = TEST_PKT_UDP_HDR_LEN;
1350 //GONE in V2 meta_tx.ploadOffBytes = TEST_PKT_PLOAD_OFFSET_BYTES;
1351 meta_tx.ploadLen = TEST_PAYLOAD_LEN;
1353 Pktlib_getDataBuffer(tip,&pData,&len);
1354 pIpHdr = pData + meta_tx.ipOffBytes;
1355 meta_tx.pseudoHdrChecksum =
1356 test_utilGetIpv4PsudoChkSum(pIpHdr,(TEST_PAYLOAD_LEN+TEST_PKT_UDP_HDR_LEN));
1358 /* post it to netcp tx channel*/
1359 meta.u.tx_meta=&meta_tx;
1360 #ifdef DEBUG_DESC
1361 if (house_pkts_gened<16) dump_descr((long *) tip, house_pkts_gened);
1362 else if (house_pkts_gened>99) dump_descr((long *) tip,house_pkts_gened);
1363 #endif
1365 if(!first)
1366 {
1367 first++;
1368 nwal_flow_vv1= netapi_timing_stop();
1369 if(nwal_initPSCmdInfo(PKTIO_GET_NWAL_INSTANCE(netcp_tx_chan),
1370 &meta_tx,
1371 &flowPSCmdInfo) != nwal_OK)
1372 {
1373 printf("nwal_initPSCmdInfo() ERROR \n");
1374 }
1375 nwal_flow_vv2= netapi_timing_stop();
1376 nwal_sum_flow_vv1 += (nwal_flow_vv1-vv1);
1377 nwal_sum_flow_vv2 += (nwal_flow_vv2-nwal_flow_vv1);
1378 }
1380 vv2= netapi_timing_stop();
1381 nwal_mCmdSetL4CkSumPort( tip,
1382 &flowPSCmdInfo,
1383 TEST_PKT_UDP_OFFSET_BYTES,
1384 (TEST_PKT_UDP_HDR_LEN + TEST_PAYLOAD_LEN),
1385 meta_tx.pseudoHdrChecksum,
1386 meta_tx.enetPort);
1388 pPktDesc = Pktlib_getDescFromPacket(tip);
1389 /* Send the packet out to transmit Q*/
1390 Qmss_queuePushDescSize (flowPSCmdInfo.txQueue,
1391 pPktDesc,
1392 NWAL_DESC_SIZE);
1393 vv3= netapi_timing_stop();
1396 sum_vv1 += (vv2-vv1);
1397 if(!house_pkts_gened)
1398 {
1399 /* first packet. Take out the PS command label creation cost */
1400 sum_vv1 = sum_vv1 - nwal_sum_flow_vv2;
1401 }
1403 sum_vv3 += (vv3-vv2);
1405 // printf("pktio send. full=%d metadata=%d pktio_send=%d\n", vv3-vv1, vv2-vv1, vv3-vv2);
1408 stats.itx +=1;
1409 house_pkts_gened +=1;
1410 }
1411 {
1412 unsigned int ccycles;
1413 int n_c_ops;
1414 ccycles =Osal_cache_op_measure(&n_c_ops);
1415 if (sum_vv1)
1416 {
1417 printf("BURST NWAL Fast send %d pkts. metadata=%d Cmd Label Creation Cost=%d nwal Fast Send Cost= %d n_c_ops=%d cache_op_time=%d (pp-> %d)\n",
1418 stats.itx, sum_vv1/stats.itx, nwal_sum_flow_vv2, sum_vv3/stats.itx,
1419 n_c_ops, ccycles, n_c_ops? (ccycles/(n_c_ops/2)) : 0);
1421 printf("NWAL Profile Cycles: Prof1= %d,Prof2=%d,Prof3=%d,Prof4=%d,Prof5=%d ,Prof6=%d \n",
1422 nwal_sum_vv1/stats.itx,nwal_sum_vv2/stats.itx,nwal_sum_vv3/stats.itx,
1423 nwal_sum_vv4/stats.itx,nwal_sum_vv5/stats.itx,nwal_sum_vv6/stats.itx);
1426 if(stats.itx2)
1427 {
1428 printf("nwal_flowSend Profile Cycles: Prof1= %d,Prof2=%d \n",
1429 nwal_sum_flow_vv1/stats.itx2,nwal_sum_flow_vv2/stats.itx2);
1430 }
1432 }
1433 }
1434 }
1437 /***************************************
1438 ********** test driver*****************
1439 ***************************************/
1440 int main(int argc, char **argv)
1441 {
1442 int err;
1443 rlim_t oss,ss = 1024*1024;
1444 struct rlimit rl;
1446 Pktlib_HeapCfg heapCfg;
1447 int32_t errCode;
1448 Pktlib_HeapIfTable* pPktifTable;
1450 err= getrlimit(RLIMIT_STACK,&rl);
1451 if (!err) printf(" stack limit = %d\n",rl.rlim_cur); else printf("getrlimit failed\n");
1452 #if 0
1453 rl.rlim_cur = ss;
1454 err=setrlimit(RLIMIT_STACK,&rl);
1455 if (!err) printf("set stack to %d\n",rl.rlim_cur); else printf("setrlimit failed\n");
1456 #endif
1458 if (argc>=2) np2process = atoi(argv[1]);
1459 if (np2process<0) np2process = NP; /* default */
1460 if (argc==3) perslow = atoi(argv[2]);
1461 if ((perslow<0)||(perslow>100)) perslow=PERSLOW;//default
1462 if (argc>3) {printf("net_test <no of pkts to process> <percent slow path>\n"); exit(1);}
1465 //real mode, so update our test packet mac header and ip header
1466 if (pktloopback==0)
1467 {
1468 memcpy(&testPkt,&real_mac_header[0],14); //overwrite test pkt mac address
1469 memcpy(&testPkt[26],&real_ip_addr[0],8);//overrite test pkt ip addresses
1470 }
1472 /*******************************************/
1473 /*************NETAPI STARTUP****************/
1474 /*******************************************/
1476 /* create netapi */
1477 netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
1479 /* open the main heap */
1480 OurHeap = Pktlib_findHeapByName("netapi");
1481 if (!OurHeap) {printf("findheapbyname fail\n"); exit(1);}
1483 /* create two secondary heaps */
1484 /* Initialize the heap configuration. */
1485 memset ((void *)&heapCfg, 0, sizeof(Pktlib_HeapCfg));
1487 pPktifTable = netapi_getPktlibIfTable();
1488 /* Populate the heap configuration */
1489 heapCfg.name = "netapi-small";
1490 heapCfg.memRegion = NETAPI_GLOBAL_REGION;
1491 heapCfg.sharedHeap = 1;
1492 heapCfg.useStarvationQueue = 0;
1493 heapCfg.dataBufferSize = 512;
1494 heapCfg.numPkts = 64;
1495 heapCfg.numZeroBufferPackets= 0;
1496 heapCfg.heapInterfaceTable.data_malloc = pPktifTable->data_malloc;
1497 heapCfg.heapInterfaceTable.data_free = pPktifTable->data_free;
1498 heapCfg.dataBufferPktThreshold = 0;
1499 heapCfg.zeroBufferPktThreshold = 0;
1501 specialSmall = Pktlib_createHeap(&heapCfg, &errCode);
1502 heapCfg.name = "netapi-big";
1503 heapCfg.dataBufferSize = 1600;
1504 specialLarge = Pktlib_createHeap(&heapCfg, &errCode);
1505 //register these heaps so poll routine will include their garbage queues.
1506 netapi_registerHeap(netapi_handle, specialSmall);
1507 netapi_registerHeap(netapi_handle, specialLarge);
1509 #ifdef REASSEMBLE_BENCH
1510 our_reassemble_bench(2);
1511 exit(1);
1512 #endif
1514 /* create a pktio channel */
1515 our_chan=pktio_create(netapi_handle,"our1stq",(PKTIO_CB) recv_cb_bench, &our_chan_cfg,&err);
1516 if (!our_chan) {printf("pktio create failed err=%d\n",err); exit(1);}
1518 /* open netcp default tx, rx queues */
1519 netcp_tx_chan= pktio_open(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err);
1520 if (!netcp_tx_chan) {printf("pktio open TX failed err=%d\n",err); exit(1);}
1521 netcp_rx_chan= pktio_open(netapi_handle, NETCP_RX, (PKTIO_CB) recv_cb, &netcp_rx_cfg, &err);
1522 if (!netcp_rx_chan) {printf("pktio open RX failed err=%d\n",err); exit(1);}
1524 /* create a pktio channel for specially classified pkts */
1525 netcp_rx_chan2= pktio_create(netapi_handle, "classq", (PKTIO_CB) recv_cb, &netcp_rx_cfg2, &err);
1526 if (!netcp_rx_chan2) {printf("pktio create RX2 failed err=%d\n",err); exit(1);}
1528 /* open netcp default tx, rx queues for sideband crypto */
1529 netcp_sb_tx_chan= pktio_open(netapi_handle, NETCP_SB_TX, NULL, &netcp_sb_tx_cfg, &err);
1530 if (!netcp_sb_tx_chan) {printf("pktio open SB TX failed err=%d\n",err); exit(1);}
1531 netcp_sb_rx_chan= pktio_open(netapi_handle, NETCP_SB_RX, (PKTIO_CB) recv_sb_cb, &netcp_sb_rx_cfg, &err);
1532 if (!netcp_sb_rx_chan) {printf("pktio open SB RX failed err=%d\n",err); exit(1);}
1534 printf("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder());
1535 /* create scheduler instance */
1536 our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
1537 if (!our_sched) {printf("sched create failed\n"); exit(1);}
1539 /********************************************
1540 * Basic pkt loopback test
1541 *********************************************/
1542 printf("...running pure push/pop benchmark\n");
1543 our_pktio_bench(1000);
1544 our_pktio_bench(1000);
1545 our_pktio_bench(1000);
1546 our_pktio_bench(1000);
1547 our_pktio_bench(1000);
1548 /*********************************************/
1553 /* add mac intefaces */
1554 netcp_cfgCreateMacInterface(
1555 netapi_handle,
1556 &mac0[0],
1557 0,0,
1558 (NETCP_CFG_ROUTE_HANDLE_T) NULL,
1559 (NETCP_CFG_VLAN_T ) NULL , //future
1560 1,
1561 &err);
1562 if (err) {printf("addmac0 failed %d\n",err); exit(1); }
1564 //attach an IP to this interface
1565 ip_rule0=netcp_addIp(
1566 netapi_handle,
1567 0,
1568 nwal_IPV4,
1569 &OurIp0,
1570 NULL, //all IP
1571 (NETCP_CFG_ROUTE_HANDLE_T) NULL,
1572 &err
1573 );
1574 if (err) {printf("addip0 failed %d\n",err); exit(1); }
1576 //create a 2nd mac instance
1577 netcp_cfgCreateMacInterface(
1578 netapi_handle,
1579 &mac1[0],
1580 1,1,
1581 (NETCP_CFG_ROUTE_HANDLE_T) NULL,
1582 (NETCP_CFG_VLAN_T ) NULL , //future
1583 1,
1584 &err);
1585 if (err) {printf("addmac1 failed %d\n",err); exit(1); }
1587 //attach an IP to this interface
1588 ip_rule1=netcp_addIp(
1589 netapi_handle,
1590 1,
1591 nwal_IPV4,
1592 &OurIp1,
1593 NULL, //all IP
1594 (NETCP_CFG_ROUTE_HANDLE_T) NULL,
1595 &err
1596 );
1597 if (err) {printf("addip1 failed %d\n",err); exit(1); }
1599 //attach 2 classifiers to iface 0, ip0
1600 class_0_cfg.u.c_l4.ip = ip_rule0;
1601 class_0 = netcp_cfgAddClass(netapi_handle,
1602 &class_0_cfg,
1603 NULL,
1604 NETCP_CFG_ACTION_TO_SW,
1605 &err);
1606 if (err) {printf("addclass0 failed %d\n",err); exit(1);}
1608 class_1_cfg.u.c_l4.ip = ip_rule0;
1609 class_1 = netcp_cfgAddClass(netapi_handle,
1610 &class_1_cfg,
1611 NULL,
1612 NETCP_CFG_ACTION_TO_SW,
1613 &err);
1614 if (err) {printf("addclass1 failed %d\n",err); exit(1);}
1617 //3rd classifier has a different IP and route
1618 class_2_cfg.u.c_l3_l4.ip_addr = &OurIp2;
1620 //create specialFlow for this classifier
1621 {
1622 Pktlib_HeapHandle heaps[2];
1623 int sizes[2];
1624 heaps[0]= specialSmall;
1625 heaps[1]= specialLarge;
1626 #define SPECIAL_SOP_OFF 128
1627 sizes[0]=512-SPECIAL_SOP_OFF;
1628 sizes[1]=1600-SPECIAL_SOP_OFF;
1629 specialFlow = netcp_cfgAddFlow( netapi_handle,
1630 2,
1631 heaps,
1632 sizes,
1633 SPECIAL_SOP_OFF, //offset to start rx is 128
1634 &err);
1635 if (err) {printf("add flow failed\n", err); exit(1);}
1636 }
1637 #if 0
1638 //special route for this classifier: different flow + destination q
1639 class2_route.p_dest_q = netcp_rx_chan2;
1640 class2_route.p_flow = specialFlow;
1641 class_2 = netcp_cfgAddClass(netapi_handle,
1642 &class_2_cfg,
1643 (void*) &class2_route,
1644 NETCP_CFG_ACTION_TO_SW,
1645 &err);
1646 if (err) {printf("addclass2 failed %d\n",err); exit(1);}
1647 #endif
1649 //security stuff
1650 ourRXKeyParams.pEncKey = &ourEncrKey[0];
1651 ourRXKeyParams.pAuthKey = &ourAuthKey[0];
1652 memcpy(&rx_sa.src, &TheirIp4IPSEC,4);
1653 memcpy(&rx_sa.dst, &OurIp4IPSEC,4);
1655 #if 1
1656 rx_tunnel = netapi_secAddSA( netapi_handle,
1657 0, //iface #0
1658 &rx_sa,
1659 &ourRXKeyParams,
1660 #ifdef IPSEC_MODE_RX_SIDEBAND
1661 NETAPI_SEC_SA_SIDEBAND,
1662 #else
1663 NETAPI_SEC_SA_INFLOW, //USE inflow mode
1664 #endif
1665 NULL, //use default route
1666 &rx_data_mode_handle,
1667 &rx_inflow_mode_handle,
1668 &err);
1669 if (err) {printf("addRxSa failed %d\n",err); exit(1);}
1671 #ifdef IPSEC_MODE_RX_INFLOW
1672 //assume inner and outer ip is the same
1673 rx_policy= netapi_secAddRxPolicy( netapi_handle,
1674 rx_tunnel, //link to tunnel above
1675 4, //ipv4
1676 &TheirIp4IPSEC, //src -> them
1677 &OurIp4IPSEC, //dst -> us
1678 NULL, // no qualifiers
1679 NULL, //default route
1680 &err);
1681 if (err) {printf("addSaPolicy failed %d\n",err); exit(1);}
1682 #else
1683 rx_policy = 0;
1684 #endif
1685 #endif
1687 //tx SA
1688 //security stuff
1689 ourTXKeyParams.pEncKey = &ourEncrKey[0];
1690 ourTXKeyParams.pAuthKey = &ourAuthKey[0];
1691 memcpy(&tx_sa.src, &OurIp4IPSEC,4);
1692 memcpy(&tx_sa.dst, &TheirIp4IPSEC,4);
1693 tx_tunnel = netapi_secAddSA( netapi_handle,
1694 0, //iface #0
1695 &tx_sa,
1696 &ourTXKeyParams,
1697 #ifdef IPSEC_MODE_TX_SIDEBAND
1698 NETAPI_SEC_SA_SIDEBAND,
1699 #else
1700 NETAPI_SEC_SA_INFLOW, //USE inflow mode
1701 #endif
1702 NULL, //use default route
1703 &tx_data_mode_handle,
1704 &tx_inflow_mode_handle,
1705 &err);
1706 if (err) {printf("addTxSa failed %d\n",err); exit(1);}
1709 #ifdef TEST_TIMERS
1710 //timers
1711 ourTimerBlock = netapi_TimerGroupCreate(
1712 netapi_handle,
1713 "our1sttimer",
1714 our_timer_cb,
1715 0, //1 if timers local to thread
1716 0, //1 if expect to cancel
1717 netapi_getTicksPerSec()/1000, /* 1 msc resolution for these timers */
1718 netapi_getTicksPerSec()/5000, /* would like .5 msc tolerence */
1719 10, //small # of timers to test garbage collection
1720 &err);
1721 if (err) {printf("timergroupcreate failed %d\n",err); exit(1);}
1723 //start a couple of timers
1724 t1 = netapi_TimerGroupStartTimer(
1725 ourTimerBlock,
1726 (void *) 1,
1727 100LL, //timer group ticks
1728 &err);
1729 if (err) {printf("timerstart failed %d\n");}
1730 t2 = netapi_TimerGroupStartTimer(
1731 ourTimerBlock,
1732 (void *) 2,
1733 200LL, //timer group ticks
1734 &err);
1735 if (err) {printf("timerstart failed %d\n");}
1736 t3 = netapi_TimerGroupStartTimer(
1737 ourTimerBlock,
1738 (void *) 3,
1739 300LL, //timer group ticks
1740 &err);
1741 if (err) {printf("timerstart failed %d\n");}
1742 #endif
1743 netcp_cfgReqStats(netapi_handle, our_stats_cb, 1,&err);
1744 if (err!=0) {printf("stats req failed\n");}
1746 /*********************************************/
1747 /*****************end NETAPI STARTUP**********/
1748 /*********************************************/
1751 /********************************************
1752 * Basic pkt loopback test
1753 *********************************************/
1754 printf("...runnining pure push/pop benchmark\n");
1755 our_pktio_bench(100);
1758 /**************unused stuff******************/
1759 /* create TRIE */
1760 P_trie = trie_new();
1761 if (!P_trie) {printf("trie alloc failed\n"); exit(1);}
1763 nat = (HEAD_T *) malloc(NE * sizeof(HEAD_T));
1764 if (!nat) {printf("malloc of nat table failed\n"); exit(1);}
1766 //gen_pkts(np2process<NP ? np2process:NP);
1767 n_pkt= np2process;
1769 /* build table */
1770 build_table(P_trie);
1773 /* processing loop: get pkt, check it, look up in table, copy new header,
1774 send packet */
1775 srand((unsigned) np2process);
1778 /*********************************************/
1779 /**************Entry point into scheduler ****/
1780 /*********************************************/
1781 netapi_schedWaitForEvents(our_sched, &err);
1783 /* done */
1784 our_stats_cb(netapi_handle, NULL);
1787 #define DO_FAST_POLL
1788 #ifdef DO_FAST_POLL
1789 example_fast_poll(netcp_rx_chan);
1790 #endif
1792 /*************************************************
1793 ************CLEAN UP****************************
1794 ************************************************/
1796 //delete Classifiers
1797 netcp_cfgDelClass(netapi_handle, class_0, &err);
1798 netcp_cfgDelClass(netapi_handle, class_1, &err);
1799 //netcp_cfgDelClass(netapi_handle, class_2, &err);
1801 //delete flow
1802 netcp_cfgDelFlow(netapi_handle, specialFlow, &err);
1804 #if 1
1805 //delete policy
1806 if (rx_policy)
1807 netapi_secDelRxPolicy(netapi_handle, rx_policy, &err);
1809 //delete tunnels
1810 netapi_secDelSA(netapi_handle, 0, rx_tunnel, &err);
1811 netapi_secDelSA(netapi_handle, 0, tx_tunnel, &err);
1812 #endif
1814 //delete IPs and MAC Interfacess
1815 netcp_cfgDelIp(netapi_handle, 0, 0, NULL, NULL, ip_rule0, &err);
1816 netcp_cfgDelIp(netapi_handle, 1, 0, NULL, NULL, ip_rule1, &err);
1817 netcp_cfgDelMac(netapi_handle,0,&err);
1818 netcp_cfgDelMac(netapi_handle,1,&err);
1821 //close pktio channels we opened
1822 pktio_close(netcp_tx_chan ,&err);
1823 pktio_close(netcp_rx_chan ,&err);
1824 pktio_close(netcp_sb_tx_chan ,&err);
1825 pktio_close(netcp_sb_rx_chan ,&err);
1827 //clear pktio channel we created
1828 pktio_control(our_chan, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);
1829 pktio_control(netcp_rx_chan2, (PKTIO_CB) NULL, (PKTIO_CFG_T *) NULL, &zap_channel_control, &err);
1831 //delete pktio channels we created
1832 pktio_delete(our_chan, &err);
1833 pktio_delete(netcp_rx_chan2,&err);
1835 netapi_shutdown(netapi_handle);
1837 }
1839 //EXAMPLE FAST POLL
1840 /* PLD */
1841 void netapi_pld(void * x)
1842 {
1843 asm volatile("pld [r0]");
1844 }
1845 #include "ti/drv/nwal/nwal_util.h"
1847 #define M 1008
1848 static int l3_off[M], l4_off[M], L3_chk_ok[M], L4_chk_ok[M], appid[M], len[M] ;
1849 static unsigned char * buf[M];
1850 #define N2POLL 8 //batch size
1851 void example_fast_poll( PKTIO_HANDLE_T * p_pktio)
1852 {
1853 int j=0;
1854 int jj=0;
1855 int i,k,l=0,ltot=0;
1856 int n= N2POLL; //max # of pkts to poll
1857 Ti_Pkt * pHd[N2POLL];
1858 Ti_Pkt * tempVA;
1859 pasahoLongInfo_t* pinfo;
1860 unsigned long t1;
1861 unsigned long t2;
1862 unsigned long t11;
1863 unsigned long t12;
1864 unsigned long np;
1865 unsigned long sumt=0;
1866 unsigned long sumf=0;
1867 unsigned long sump=0;
1868 unsigned long totlen=0;
1869 int max_batch=0;
1871 //this should be done once and saved
1872 Qmss_QueueHnd rxQ= PKTIO_GET_DEFAULT_NETCP_Q(p_pktio);
1873 Qmss_QueueHnd freeQ;
1874 //loop forever
1875 for(;;)
1876 {
1877 t1= netapi_timing_stop();
1878 pHd[0] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
1879 if (!pHd[0]) continue;
1880 //got pkt
1881 for(i=1;(i<n) && (pHd[i-1]);i++)
1882 {
1883 //convert previous descriptor PA -> VA
1884 tempVA = Osal_qmssPhyToVirt(pHd[i-1]);
1886 //try and preload desriptor
1887 __builtin_prefetch(tempVA);
1888 //netapi_pld(tempVA);
1890 //read next descriptor from queue
1891 pHd[i] = (Ti_Pkt *)QMSS_DESC_PTR(PKTIO_QMSS_QUEUE_POP_RAW (rxQ));
1892 #if 1
1893 /* extract some meta data */
1894 Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]);
1895 pinfo = PKTIO_GET_PROTO_INFO(tempVA);
1896 l3_off[jj]= PKTIO_GET_L3_OFFSET(pinfo);
1897 l4_off[jj]= PKTIO_GET_L4_OFFSET(pinfo);
1898 appid[jj]= PKTIO_GET_APPID(tempVA);
1899 //#define VERIFY_SOP
1900 #ifdef VERIFY_SOP
1901 if (sump < 200) printf("..sop off=%d\n", (int) buf[jj]-
1902 (int) ((Cppi_HostDesc *) tempVA)->origBuffPtr) ;
1903 #endif
1904 #endif
1905 jj+=1;
1906 }
1907 //finish last pkt in burst
1908 if(pHd[i-1])
1909 {
1910 //convert previous descriptor PA -> VA
1911 tempVA = Osal_qmssPhyToVirt(pHd[i-1]);
1913 /* extract some meta data */
1914 #if 1
1915 pinfo = PKTIO_GET_PROTO_INFO(tempVA);
1916 l3_off[jj]= PKTIO_GET_L3_OFFSET(pinfo);
1917 l4_off[jj]= PKTIO_GET_L4_OFFSET(pinfo);
1918 appid[jj]= PKTIO_GET_APPID(tempVA);
1919 #endif
1920 //get ptr (Physical address) and length of associate buffer
1921 Cppi_getData (Cppi_DescType_HOST, (Cppi_Desc*)tempVA, &buf[jj], &len[jj]);
1922 jj+=1;
1923 }
1924 t2= netapi_timing_stop();
1925 j+=(pHd[i-1]? i: (i-1)) ;
1926 if (jj>(M-n)) jj=0;
1927 l+=1; //n batches
1928 ltot+=1;
1929 if(pHd[i-1])
1930 {
1931 if (i>max_batch) max_batch= i;
1932 }
1933 else
1934 {
1935 if( (i-1) >max_batch) max_batch = i-1;
1936 }
1938 //cleanup
1939 //printf("cleanup %d\n",i);
1940 for(k=0;k<i;k++)
1941 {
1942 //cleanup. need to covert all of desriptor to VA so that i can use freePacket()
1943 //alternative would be to just do cache ops plus descriptor raw push to pktlib
1944 // heap free queue
1945 if(pHd[k])
1946 {
1948 //tempVA=Qmss_osalConvertDescPhyToVirt(pHd[k]);
1949 tempVA = Osal_qmssPhyToVirt(pHd[k]);
1950 freeQ=Qmss_getQueueHandle(Cppi_getReturnQueue (Cppi_DescType_HOST, tempVA));
1951 netapi_utilCacheWbInv(tempVA,128);
1952 //would need to wbInv buffer also in practice. Also need to walk
1953 // descriptor chain
1954 t11= netapi_timing_stop();
1955 // Pktlib_freePacket(tempVA);
1956 PKTIO_QMSS_QUEUE_PUSH_DESC_SIZE_RAW (freeQ,
1957 (void *) pHd[k],
1958 128);
1960 t12= netapi_timing_stop();
1961 sumf += (t12-t11);
1962 }
1963 }
1964 sumt += (t2-t1);
1965 sump +=(pHd[i-1]? i: (i-1));
1966 //printf("end cleanup %d %d %d\n",sumt,sumf,sump );
1967 if (sump > 10000) {
1968 printf("pkts rx %d batches=%d appid=%x l3_off=%d l4_off=%d len=%d buf=0x%x rxcycle= %d pkts/batchx1000=%d maxbatch=%d cycles per rawpush = %d\n",
1969 j,ltot, appid[j%M],
1970 l3_off[j%M],l4_off[j%M],
1971 len[j%M],buf[j%M],
1972 sumt/sump, (sump*1000)/l, max_batch,
1973 sumf/sump);
1974 sumt=sump=sumf=0;
1975 l=0;
1976 }
1977 }
1980 }