1 /******************************************************************************
2 * File: net_test_router.c
3 * Purpose: net_test_router application
4 ******************************************************************************
5 * FILE: net_test_router.c
6 *
7 * DESCRIPTION: netapi user space transport
8 * library net_test_router application
9 *
10 * REVISION HISTORY:
11 *
12 * Copyright (c) Texas Instruments Incorporated 2013
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 "trie.h"
46 #include <signal.h>
47 #include <pthread.h>
48 #include <sys/resource.h>
49 #include "router.h"
50 extern int QUIT;
53 #if defined(DEVICE_K2H)
54 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
55 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
56 #elif defined (DEVICE_K2K)
57 #include <ti/drv/qmss/device/k2k/src/qmss_device.c>
58 #include <ti/drv/cppi/device/k2k/src/cppi_device.c>
59 #elif defined (DEVICE_K2L)
60 #include <ti/drv/qmss/device/k2l/src/qmss_device.c>
61 #include <ti/drv/cppi/device/k2l/src/cppi_device.c>
62 #elif defined (DEVICE_K2E)
63 #include <ti/drv/qmss/device/k2e/src/qmss_device.c>
64 #include <ti/drv/cppi/device/k2e/src/cppi_device.c>
65 #else /*Default */
66 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
67 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
68 #endif
69 /* Global definitions */
71 netTestConfig_t netTestCfg;
72 static netTestConfigFile_t config_file;
74 char input_file_name[] = "/etc/netapi/net_test_config.txt";
76 nwal_RetValue nwalRetVal;
77 Pktlib_HeapHandle ourHeap;
79 PKTIO_HANDLE_T *netcp_tx_chan_no_crypto;
80 PKTIO_HANDLE_T *netcp_rx_chan;
81 PKTIO_HANDLE_T *netcp_tx_chan_esp;
82 PKTIO_HANDLE_T *netcp_tx_chan_ah;
87 PKTIO_CFG_T netcp_rx_cfg={PKTIO_RX, PKTIO_NA, PKTIO_NA, 8};
88 PKTIO_CFG_T netcp_tx_cfg={PKTIO_TX, PKTIO_NA, PKTIO_NA, 8};
92 NETCP_CFG_EXCEPTION_PKT_T expPkt_appid;
94 Trie *p_trie_sa_rx;
95 Trie *p_trie_sa_tx;
98 #include "router.c"
99 Trie * our_router;
101 OUR_ROUTE_T routes[MAX_ROUTES]=
103 {
104 {0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0},
105 {0,{0x00,0x00,0x0,0x00,0x0,0x0, 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00},0},
106 {0,{0xD4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x14,0x02,0x08,0x00},0},
107 {0,{0x00,0x15,0x60,0xa1,0xf7,0xbe, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0},
108 {0,{0xd4,0xbe,0xd9,0x00,0xd3,0x7e, 0x00,0x01,0x02,0x03,0x04,0x05,0x08,0x00},0}
109 };
110 unsigned int ip[MAX_ROUTES]={BE(0x0a0100c8),BE(0x0a00000a),BE(0x0a02000a),BE(0xc0a8010a),BE(0x9eda6719)};
112 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
113 PKTIO_METADATA_T meta[], int n_pkts,
114 uint64_t ts );
117 extern netTestStats_T stats[TUNE_NETAPI_NUM_CORES];
118 extern paSysStats_t netcp_stats;
120 /*******************************************
121 *************NETAPI OBJECTS***************
122 *****************************************/
123 static NETAPI_CFG_T our_netapi_default_cfg=
124 {
125 TUNE_NETAPI_PERM_MEM_SZ,
126 128, //start of packet offset for hw to place data on rx for default flow
127 TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
128 TUNE_NETAPI_NUM_GLOBAL_DESC, //total we will use
129 TUNE_NETAPI_DEFAULT_NUM_BUFFERS, //#descriptors+buffers in default heap
130 64, //#descriptors w/o buffers in default heap
131 TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128, //size of buffers in default heap
132 128, //tail room
133 256, //extra room
134 0
135 };
139 void house(NETAPI_SCHED_HANDLE_T *s);
140 NETAPI_T netapi_handle;
141 NETAPI_SCHED_HANDLE_T * our_sched;
142 #ifdef netTest_MULTI_THREAD
143 NETAPI_SCHED_HANDLE_T * scheduler[TUNE_NETAPI_NUM_CORES];
144 #endif
145 NETAPI_SCHED_CONFIG_T our_sched_cfg={
146 NETAPI_SCHED_DURATION|NETAPI_SCHED_CBV, 0, house, 5000000 //every 5000000 poll loops
147 };
150 NETCP_CFG_IP_T ip_rule[NET_TEST_MAX_IP];
151 NETCP_CFG_MACIF_T mac[NET_TEST_MAX_MAC];
155 /* security objects. (for loopback mode) */
156 netTestSA_t sa_info[MAX_SEC_INDEX];
159 NETCP_CFG_IPSEC_POLICY_T rx_policy[MAX_SEC_INDEX];
164 /*************************END NETAPI OBJECTS***********************/
166 void update_header(netTestHead_T * p_head, int len)
167 {
168 unsigned char *p = (unsigned char *) &p_head->udp[1];
169 len -= (20+14);
170 /* update ip checksum */
171 /* update udp checksum */
172 /* update length */
173 *p= (len&0xff00)>>8;
174 *(p+1) = len&0xff;
175 }
177 #ifdef netTest_MULTI_THREAD
178 /* Templates to build command labels at startup up time, required by open_pktio_tx_channels() */
179 nwalTxPktInfo_t txPktInfoESP =
180 {
181 NULL, /* p_pkt */
182 NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO| NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID, /* txFlags */
183 0, /* lpbackPass */
184 1, /* enetport */
185 0, /* msuSize */
186 0, /* startOffset */
187 netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN, /* saOffBytes */
188 0, /* saPayLoadLen */
189 0 , /* saAhIcvOffBytes */
190 0, /* saAhMacSize */
191 0, /* etherLenOffBytes */
192 netTest_MAC_HEADER_LEN, /* ipOffBytes */
193 0, /* l4OffBytes */
194 0, /* l4HdrLen */
195 0, /* pseudoHdrChecksum */
196 0 /* pLoadLen */
197 };
200 nwalTxPktInfo_t txPktInfoAH =
201 {
202 NULL, /* p_pkt */
203 NWAL_TX_FLAG1_DO_IPSEC_AH_CRYPTO| NWAL_TX_FLAG1_DO_IPV4_CHKSUM | NWAL_TX_FLAG1_META_DATA_VALID, /* txFlags */
204 0, /* lpbackPass */
205 0, /* enetport */
206 0, /* msuSize */
207 0, /* startOffset */
208 netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN, /* saOffBytes */
209 0, /* saPayLoadLen */
210 netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN + netTest_IPSEC_AH_FIXED_HDR_SIZE, /* saAhIcvOffBytes */
211 12, /* saAhMacSize */
212 0, /* etherLenOffBytes */
213 netTest_MAC_HEADER_LEN, /* ipOffBytes */
214 0, /* l4OffBytes */
215 netTest_UDP_HEADER_LEN, /* l4HdrLen */
216 0, /* pseudoHdrChecksum */
217 0 /* pLoadLen */
218 };
220 nwalTxPktInfo_t txPktInfoNoCrypto =
221 {
222 NULL, /* p_pkt */
223 NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID, /* txFlags */
224 0, /* lpbackPass */
225 0, /* enetport */
226 0, /* msuSize */
227 0, /* startOffset */
228 0, /* saOffBytes */
229 0, /* saPayLoadLen */
230 0 , /* saAhIcvOffBytes */
231 0, /* saAhMacSize */
232 0, /* etherLenOffBytes */
233 netTest_MAC_HEADER_LEN, /* ipOffBytes */
234 netTest_MAC_HEADER_LEN +netTest_IP_HEADER_LEN, /* l4OffBytes */
235 netTest_UDP_HEADER_LEN, /* l4HdrLen */
236 0, /* pseudoHdrChecksum */
237 0 /* pLoadLen */
238 };
240 void close_pktio_channels(void)
241 {
242 int err;
243 netapi_pktioClose(netcp_tx_chan_no_crypto ,&err);
244 netapi_pktioClose(netcp_tx_chan_esp ,&err);
245 netapi_pktioClose(netcp_tx_chan_ah ,&err);
246 }
250 void open_pktio_tx_channels()
251 {
252 int err;
253 /* open netcp default TX channels for non-ipsec*/
254 netcp_tx_chan_no_crypto= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err);
255 if (!netcp_tx_chan_no_crypto)
256 {
257 netapi_Log("pktio open TX failed err=%d\n",err);
258 exit(1);
259 }
260 else
261 {
262 PKTIO_CONTROL_T control;
263 control.op = PKTIO_UPDATE_FAST_PATH;
264 PKTIO_CFG_T cfg;
265 cfg.fast_path_cfg.fp_send_option = PKTIO_FP_NO_CRYPTO_NO_CKSUM_PORT;
266 cfg.fast_path_cfg.txPktInfo= &txPktInfoNoCrypto;
267 netapi_pktioControl(netcp_tx_chan_no_crypto, NULL, &cfg, &control, &err);
268 }
269 /* open netcp default TX for ESP packets */
270 netcp_tx_chan_esp= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err);
271 if (!netcp_tx_chan_esp)
272 {
273 netapi_Log("pktio open TX failed err=%d\n",err);
274 exit(1);
275 }
276 else
277 {
278 if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
279 {
280 PKTIO_CONTROL_T control;
281 control.op = PKTIO_UPDATE_FAST_PATH;
282 PKTIO_CFG_T cfg;
283 cfg.fast_path_cfg.fp_send_option = PKTIO_FP_ESP_L3CKSUM_PORT;
284 cfg.fast_path_cfg.txPktInfo= &txPktInfoESP;
285 netapi_pktioControl(netcp_tx_chan_esp, NULL, &cfg, &control, &err);
286 }
287 }
289 /*/* open netcp default TX for AH packets */
290 netcp_tx_chan_ah= netapi_pktioOpen(netapi_handle, NETCP_TX, NULL, &netcp_tx_cfg, &err);
291 if (!netcp_tx_chan_ah)
292 {
293 netapi_Log("pktio open TX failed err=%d\n",err);
294 exit(1);
295 }
296 else
297 {
298 if(netTestCfg.ipsec_mode_tx == IPSEC_MODE_TX_INFLOW)
299 {
300 PKTIO_CONTROL_T control;
301 control.op = PKTIO_UPDATE_FAST_PATH;
302 PKTIO_CFG_T cfg;
303 cfg.fast_path_cfg.fp_send_option = PKTIO_FP_AH_PORT;
304 cfg.fast_path_cfg.txPktInfo= &txPktInfoAH;
305 netapi_pktioControl(netcp_tx_chan_ah, NULL, &cfg, &control, &err);
306 }
307 }
308 }
313 NETAPI_T worker_nh[TUNE_NETAPI_NUM_CORES];
314 void slow_path_thread(uint32_t index)
315 {
316 int err,i;
317 uint32_t thread_num;
318 PKTIO_HANDLE_T *rx_chan;
319 PKTIO_HANDLE_T *sb_tx_chan;
320 PKTIO_HANDLE_T *sb_rx_chan;
321 cpu_set_t cpu_set;
323 thread_num = netTestCfg.sp_thread_num[index];
324 printf("slow_path_thread for index %d called for thread %d\n", index, thread_num);
326 CPU_ZERO( &cpu_set);
327 #ifdef CORTEX_A8
328 for (i = netTestCfg.sp_proc_start[index]; i <= netTestCfg.sp_proc_end[index];i++)
329 {
330 printf("slow_path_thread: setting cpu %d to cpu_set\n", i);
331 CPU_SET( i, &cpu_set);
332 }
333 hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
334 #else
335 for (i = netTestCfg.sp_proc_start[index]; i <= netTestCfg.sp_proc_end[index];i++)
336 {
337 printf("slow_path_thread: setting cpu %d to cpu_set\n", i);
338 CPU_SET( i, &cpu_set);
339 }
340 hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);
341 #endif
342 worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,
343 NULL);
344 if (worker_nh[thread_num] == NULL)
345 {
346 printf("slow_path_thread: netapi_init failure, exiting\n");
347 exit(1);
348 }
349 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) worker_nh[thread_num];
351 /* open netcp RX channel */
352 //rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg, &err);
356 netapi_setCookie(worker_nh[thread_num],(void*) (thread_num | NET_TEST_SP_THREAD_MASK));
358 scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err);
359 if (!scheduler[thread_num])
360 {
361 netapi_Log("sched create failed for core%d\n",thread_num);
362 exit(1);
363 }
364 scheduler[thread_num]->config.yield = FALSE;
365 scheduler[thread_num]->config.pollGarbageQ = TRUE;
366 scheduler[thread_num]->config.pollCtrlQ = TRUE;
367 /*********************************************/
368 /**************Entry point into scheduler ****/
369 /*********************************************/
370 netapi_schedRun(scheduler[thread_num], &err);
371 netapi_Log("slow_path_thread: core %d worker thread done\n",thread_num);
373 //netapi_pktioClose(rx_chan, &err);
374 netapi_shutdown(worker_nh[thread_num]);
375 }
378 void fast_path_thread(uint32_t index)
379 {
380 int err,i;
381 uint32_t thread_num;
382 PKTIO_HANDLE_T *rx_chan;
383 PKTIO_HANDLE_T *sb_tx_chan;
385 cpu_set_t cpu_set;
387 thread_num = netTestCfg.fp_thread_num[index];
388 printf("fast_path_thread for index %d called for thread %d\n", index, thread_num);
389 CPU_ZERO( &cpu_set);
390 #ifdef CORTEX_A8
391 for (i = netTestCfg.fp_proc_start[index]; i <= netTestCfg.fp_proc_end[index];i++)
392 {
393 printf("fast_path_thread: setting cpu %d to cpu_set\n", i);
394 CPU_SET( i, &cpu_set);
395 }
396 hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);
397 #else
398 for (i = netTestCfg.fp_proc_start[index]; i <= netTestCfg.fp_proc_end[index];i++)
399 {
400 printf("fast_path_thread: setting cpu %d to cpu_set\n", i);
401 CPU_SET( i, &cpu_set);
402 }
403 hplib_utilSetupThread(thread_num, &cpu_set, hplib_spinLock_Type_LOL);
404 #endif
405 worker_nh[thread_num]=netapi_init(NETAPI_CORE_MASTER,
406 NULL);
407 if (worker_nh[thread_num] == NULL)
408 {
409 printf("fast_path_thread: netapi_init failure, exiting\n");
410 exit(1);
411 }
412 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) worker_nh[thread_num];
414 /* open netcp RX channel */
415 rx_chan = netapi_pktioOpen(worker_nh[thread_num], NETCP_RX, (PKTIO_CB) recv_cb_router, &netcp_rx_cfg, &err);
416 netapi_setCookie(worker_nh[thread_num],(void*)thread_num);
418 scheduler[thread_num] =netapi_schedOpen(worker_nh[thread_num],&our_sched_cfg, &err);
419 if (!scheduler[thread_num])
420 {
421 netapi_Log("sched create failed for core%d\n",thread_num);
422 exit(1);
423 }
425 /*********************************************/
426 /**************Entry point into scheduler ****/
427 /*********************************************/
428 scheduler[thread_num]->config.yield = FALSE;
429 scheduler[thread_num]->config.pollGarbageQ = FALSE;
430 scheduler[thread_num]->config.pollCtrlQ = FALSE;
431 //sleep(100000);
432 netapi_schedRun(scheduler[thread_num], &err);
433 netapi_Log("fast_path_thread: core %d worker thread done\n",thread_num);
435 netapi_pktioClose(rx_chan, &err);
436 netapi_shutdown(worker_nh[thread_num]);
437 }
438 #endif
440 /***************************************
441 ********** test driver*****************
442 ***************************************/
443 int main(int argc, char **argv)
444 {
445 int err,i;
446 Pktlib_HeapCfg heapCfg;
447 int32_t errCode;
448 Pktlib_HeapIfTable* pPktifTable;
449 FILE * fpr = NULL;
451 cpu_set_t cpu_set;
452 /* install signal handler for ^c */
453 signal(SIGINT,netTest_utilMySig);
455 if (argc == 2)
456 {
457 fpr = fopen(argv[1], "r");
458 }
459 else
460 {
461 fpr = fopen(input_file_name, "r");
462 }
463 if (fpr == NULL)
464 {
465 exit(1);
466 }
467 else
468 {
469 memset(&config_file, 0, sizeof(netTestConfigFile_t));
470 memset(&netTestCfg, 0, sizeof(netTestConfig_t));
471 netTest_utilProcessConfigFile(fpr,&config_file);
472 netTest_utilParseMac(&config_file);
474 /* parse slow path/fast path thread configuration parameters */
475 netTest_utilParseThreadParams(&config_file);
477 netTest_utilParseIP(&config_file);
479 netTest_utilParseIpsecMode(&config_file);
481 /* DSP mac processing */
482 parse_dsp_mac(&config_file.dsp_mac[0]);
484 /* DSP IP processing */
485 parse_dsp_ip(&config_file.dsp_ip[0]);
487 netTest_utilParseRoutes(&config_file, &routes[0], &our_router);
489 /* IPSEC interface number processing */
490 parse_simple_param_u32((char*)&config_file.ipsec_if_no[0], &netTestCfg.ipsec_if_no);
492 netTest_utilParseSA(&config_file);
493 }
495 memset(&sa_info, 0, sizeof(sa_info));
497 #ifdef netTest_MULTI_THREAD
498 /* assign main net_test thread to run on core 0 */
499 CPU_ZERO( &cpu_set);
500 CPU_SET( 0, &cpu_set);
501 hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
502 #endif
503 /* create netapi */
504 netapi_handle = netapi_init(NETAPI_SYS_MASTER,
505 &our_netapi_default_cfg);
507 if (netapi_handle == NULL)
508 {
509 printf("main: netapi_init failure, exiting\n");
510 exit(1);
511 }
512 /* configure expection packet handling with netapi */
513 netapi_netcpCfgExceptions(netapi_handle, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_DISCARD, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
514 expPkt_appid = netapi_netcpCfgExceptions(netapi_handle, 7, NETCP_CFG_ACTION_TO_SW, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
516 /* open the main heap */
517 ourHeap = Pktlib_findHeapByName("netapi");
518 if (!ourHeap)
519 {
520 netapi_Log("Pktlib_findHeapByName() fail\n");
521 exit(1);
522 }
524 /* Open all required PKTIO TX channels */
525 open_pktio_tx_channels();
527 netapi_Log("net_test> %d bytes left in our CMA area\n", netapi_getBufMemRemainder());
528 /* create scheduler instance */
529 our_sched =netapi_schedOpen(netapi_handle,&our_sched_cfg, &err);
530 if (!our_sched) {netapi_Log("sched create failed\n"); exit(1);}
533 /*create net_test MAC interfaces, attach IP to created MAC interfaces */
534 netTest_utilCreateInterfaces(netTestCfg.num_macs, netTestCfg.num_ips);
536 /* Lookup Database for SA context, this is used by packet processing routines to get RX and TX SA information*/
537 p_trie_sa_rx = trie_new();
538 p_trie_sa_tx = trie_new();
539 if (!p_trie_sa_rx || !p_trie_sa_tx)
540 {netapi_Log("trie alloc for SA failed\n"); exit(1);}
542 /* Create RX SA's, RX Policy and TX SA's, all SA configuration parameters are read from net_test_config.txt file */
543 netTest_utilCreateSecAssoc();
546 #ifdef netTest_MULTI_THREAD
547 {
548 char c;
549 /* create and set affinity of slow path and fast path threads to
550 * specific CPU cores as specified in the net_test_config.txt file */
551 netTest_utilCreateSpFpThreads(netTestCfg.num_sp_threads,
552 (NET_TEST_FUNC_PTR) slow_path_thread,
553 netTestCfg.num_fp_threads,
554 (NET_TEST_FUNC_PTR) fast_path_thread);
556 //this thread of execution (main) now just waits on user input
557 for(;;)
558 {
559 printf(">");
560 c=getchar();
561 if (c=='q') {QUIT=1;break;}
562 else if (c=='s') netTest_utilsStatsCb(netapi_handle, &netcp_stats);
563 else if (c=='h') printf("'q' to quit, 's' for stats, 'h' for help\n");
564 }
565 netTest_utilRemoveSpFpThreads(netTestCfg.num_sp_threads, netTestCfg.num_fp_threads);
566 }
567 #else
568 /*********************************************/
569 /**************Entry point into scheduler ****/
570 /*********************************************/
571 netapi_schedRun(our_sched, &err);
572 #endif
574 /* done */
575 netTest_utilsStatsCb(netapi_handle, NULL);
579 /* cleanup*/
580 netTest_utilDeleteSecAssoc();
581 netTest_utilDeleteInterfaces(netTestCfg.num_macs, netTestCfg.num_ips);
583 /* close pktio channels we opened via open_pktio_tx_channels() */
584 close_pktio_channels();
585 netapi_shutdown(netapi_handle);
586 }
588 static inline void send_it(Ti_Pkt *tip, int len, netTestSA_t * p_sec, int out_port)
589 {
590 unsigned long st1;
591 unsigned long st2;
592 int err=0;
593 PKTIO_METADATA_T meta2 = {PKTIO_META_TX,{0},0};
594 nwalTxPktInfo_t meta_tx2={0};
595 st1=hplib_mUtilGetPmuCCNT();
596 #ifdef netTest_MULTI_THREAD
597 int coreid=Osal_nwalGetProcId(); //who we are(thread local)
598 //int coreid = our_core;
599 #else
600 int coreid=0;
601 #endif
602 if (len<60)
603 {
604 unsigned int templen;
605 char * p_pkt;
606 len=60;
607 Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
608 Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
609 stats[coreid].tx_min+=1;
610 }
611 Pktlib_setPacketLen(tip,len);
612 meta_tx2.txFlag1 = (NWAL_TX_FLAG1_DO_IPV4_CHKSUM| NWAL_TX_FLAG1_META_DATA_VALID );
613 meta_tx2.startOffset = 0;
614 meta_tx2.ipOffBytes = netTest_MAC_HEADER_LEN;
615 meta_tx2.ploadLen = len ;
616 meta_tx2.enetPort=out_port;
617 if(p_sec)
618 {
619 meta_tx2.txFlag1 |= NWAL_TX_FLAG1_DO_IPSEC_ESP_CRYPTO ;
620 meta2.sa_handle = (void*)p_sec->tx_tunnel;
621 meta_tx2.saOffBytes=netTest_MAC_HEADER_LEN + netTest_IP_HEADER_LEN;
622 meta_tx2.saPayloadLen=len-netTest_MAC_HEADER_LEN - netTest_IP_HEADER_LEN; //don't include tag, mac and outer header
623 meta2.u.tx_meta=&meta_tx2;
624 netapi_pktioSend(netcp_tx_chan_esp,tip,&meta2,&err);
625 stats[coreid].sec_tx+=1;
626 }
627 else
628 {
629 meta2.u.tx_meta=&meta_tx2;
630 netapi_pktioSend(netcp_tx_chan_no_crypto,tip,&meta2,&err);
632 }
633 stats[coreid].tx +=1;
634 st2=hplib_mUtilGetPmuCCNT();
635 stats[coreid].send_cycles += (unsigned long long) (st2-st1);
636 }
637 void recv_cb_router(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
638 PKTIO_METADATA_T meta[], int n_pkts,
639 uint64_t ts )
640 {
641 int i;
642 int len;
643 int p;
644 Ti_Pkt * tip;
645 unsigned int templen;
646 char * p_pkt;
647 netTestHead_T temp_head;
648 unsigned int appid;
649 IP_netTestHead_T th;
650 netTestSA_t *sec_data=NULL;
651 unsigned long t1;
652 unsigned long t2;
653 unsigned long long ct1;
654 unsigned long long ct2;
655 unsigned short ip_pl;
656 unsigned long long n_c_ops;
657 int ifno;
658 int out_port;
659 #ifdef netTest_MULTI_THREAD
660 int coreid=Osal_nwalGetProcId(); //who we are(thread local)
661 //int coreid = our_core;
662 #else
663 int coreid=0;
664 #endif
665 t1=hplib_mUtilGetPmuCCNT();
666 ct1 =Osal_cache_op_measure(&n_c_ops);
667 for(i=0;i<n_pkts;i++)
668 {
669 ifno = ((unsigned int)meta[i].u.rx_meta->appId)&0xff;
670 if(coreid<TUNE_NETAPI_NUM_CORES) stats[coreid].rx+=1;
671 if (ifno < TUNE_NETAPI_MAX_NUM_MAC) stats[coreid].if_rx[ifno]+=1;
672 tip = p_recv[i];
673 Pktlib_getDataBuffer(tip,(uint8_t**)&p_pkt,&templen);//ignore templen
674 len = Pktlib_getPacketLen(tip)-4;//real length, subtract mac trailer
675 appid = ((unsigned int)meta[i].u.rx_meta->appId)&0xff000000;
676 switch(appid)
677 {
678 case(NETAPI_NETCP_MATCH_IPSEC):
679 case(NETAPI_NETCP_MATCH_IPSEC_POLICY):
680 {
681 int tailen=12+2;
682 memcpy(&temp_head,&p_pkt[14],sizeof(netTestHead_T));
683 if (!netTest_utilCheckHeader(&temp_head,&meta[i])) {
684 stats[coreid].n_bad+=1;
685 Pktlib_freePacket(tip);
686 continue;
687 }
688 tailen+=p_pkt[len-12-2]; //padding length (12)should come from sec_ptr
689 p_pkt = &p_pkt[8+16+20]; //16= iv len, should come from sec_ptr
690 len -= (8+16+20+tailen); //16= iv len should come from sec ptr
692 //now check inner headder.
693 memcpy(&th,&p_pkt[14],20);
694 if (!netTest_utilCheckHeader(&temp_head,&meta[i])) {
695 stats[coreid].n_bad+=1;
696 Pktlib_freePacket(tip);
697 continue;
698 }
699 Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc *) tip, p_pkt,len);
700 Pktlib_setPacketLen(tip,len);
702 if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data,&out_port)<0)
703 {
704 stats[coreid].n_bad+=1;
705 Pktlib_freePacket(tip);
706 }
707 else
708 {
709 send_it(tip,len,sec_data,out_port);
710 }
711 break;
712 }
713 case(NETAPI_NETCP_MATCH_GENERIC_MAC):
714 if((p_pkt[12]!=0x8)||(p_pkt[13]!=0x00))
715 {
716 stats[coreid].n_new+=1;
717 Pktlib_freePacket(tip);
718 continue;
719 }
720 if (!netTest_utilCheckHeader(&temp_head,&meta[i]))
721 {
722 stats[coreid].n_bad+=1;
723 Pktlib_freePacket(tip);
724 continue;
725 }
726 memcpy(&th,&p_pkt[14],20);
727 ip_pl= (((unsigned char *)&th.w1)[2]<<8) | ((unsigned char *)&th.w1)[3];
728 if ((ip_pl+14)<60)
729 {
730 len-= (60-(ip_pl+14));
731 stats[coreid].rx_min+=1;
732 }
733 Pktlib_setPacketLen(tip,len);
734 if (route_pkt(our_router, tip, &th, p_pkt, &len,&sec_data,&out_port)<0)
735 {
736 stats[coreid].n_bad+=1;
737 Pktlib_freePacket(tip);
738 }
739 else
740 {
741 send_it(tip,len,sec_data,out_port);
742 }
743 break;
744 case(NETAPI_NETCP_MATCH_GENERIC_IP):
745 Pktlib_freePacket(tip);
746 stats[coreid].n_new=1;
747 break;
748 default:
749 stats[coreid].n_new+=1;
750 Pktlib_freePacket(tip);
751 break;
752 }
753 }
754 t2=hplib_mUtilGetPmuCCNT();
755 ct2 =Osal_cache_op_measure(&n_c_ops);
756 stats[coreid].app_cycles += (unsigned long long) (t2-t1);
757 stats[coreid].tx_cache_cycles += (unsigned long long) (ct2-ct1);
758 return;
759 }
761 /* STUB functions required for compilation */
762 void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
763 PKTIO_METADATA_T meta[], int n_pkts,
764 uint64_t ts )
765 {
766 }
768 void recv_sb_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
769 PKTIO_METADATA_T meta[], int n_pkts,
770 uint64_t ts )
771 {
772 }