8e95419a79c7205791056d7c74f0ae03b821c45e
[keystone-rtos/netapi.git] / ti / runtime / netapi / applications / ipsec_offload / ipsecmgr / src / netapi_ipsecmgr.c
1 /*
2  * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
3  *
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions
7  *  are met:
8  *
9  *    Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *    Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *    Neither the name of Texas Instruments Incorporated nor the names of
18  *    its contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33 */
36 /* IPSec Manager Include Files */
37 #include "ipsecmgr_snoop.h"
38 #include "ipsecmgr_ipc.h"
39 #include "ipsecmgr_syslog.h"
41 /* Local include */
42 #include "netapilib_interface.h"
44 /* Standard includes */
45 #include <dlfcn.h>
46 #include <stdlib.h>
47 #include <signal.h>
48 #include <stdarg.h>
52 #include <arpa/inet.h>
53 #include <sys/socket.h>
54 #include <ifaddrs.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <unistd.h>
59 #include <sys/types.h>
60 #include <netinet/in.h> 
61 #include <string.h> 
63 /**********************************************************************
64  ************************** Local Definitions *************************
65  **********************************************************************/
66 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
67  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
68 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
69 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
72 /**********************************************************************
73  ************************** Global Variables **************************
74  **********************************************************************/
76 static ipsecmgr_ipc_daemon_send_if_t *send_iface;
77 NETAPI_T netapi_handle;
79 //paSysStats_t netcp_stats;
80 ipsecMgrMcb_t globalDB;
82 /* Lock file for the daemon */
83 #define LOCK_FILE   "/var/lock/ipsecmgr_daemon"
85 /* snoop task */
86 static pthread_t    snoop_run_th;
88 static NETAPI_CFG_T our_netapi_default_cfg=
89 {
90     TUNE_NETAPI_PERM_MEM_SZ,
91     128,  //start of packet offset for hw to place data on rx for default flow
92     TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
93     TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
94     TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
95     64, //#descriptors w/o buffers in default heap
96     TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
97     128,    //tail room
98     256,    //extra room
99     0
100 };
104 static int QUIT = 0;
106 /* stub functions */
107 static void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
108                          PKTIO_METADATA_T meta[], int n_pkts,
109                          uint64_t ts )
111     return;
114 /* byte swap routine */
115 static unsigned int swap32 (unsigned int x)
117     unsigned int y;
119     y = (((x >> 24) & 0xff) <<  0) |
120         (((x >> 16) & 0xff) <<  8) |
121         (((x >>  8) & 0xff) << 16) |
122         (((x >>  0) & 0xff) << 24) ;
124     return (y);
128 void cleanup_sa_sp()
130     int slot, error=0;;
131     /* delete any offloaded rx SA's and policies */
132     /* and delete any offloaded tx SA's */
133     for (slot = 0;slot < 64;slot++)
134     {
135         if(globalDB.rx_sa[slot].in_use)
136         {
137             globalDB.rx_sa[slot].in_use = 0;
138             if(globalDB.rx_sa[slot].spAppId)
139             {
140                 netapi_secDelRxPolicy(netapi_handle,
141                               (NETCP_CFG_IPSEC_POLICY_T) globalDB.rx_sa[slot].spAppId,
142                               &error);
143                 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
144                 "cleanup_sa_sp: SP deleted: sp_app_id: 0x%x, slot: %d, error: %d\n", 
145                 globalDB.rx_sa[slot].spAppId, slot, error);
146             }
147             netapi_secDelSA(netapi_handle,
148                         NETCP_CFG_NO_INTERFACE,
149                         (NETCP_CFG_SA_T) globalDB.rx_sa[slot].saAppId,
150                         &error);
151             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
152                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
153                 globalDB.rx_sa[slot].saAppId, slot, error);
154             
155         }
156         if(globalDB.tx_sa[slot].in_use)
157         {
158             globalDB.tx_sa[slot].in_use = 0;
159             netapi_secDelSA(netapi_handle,
160                             NETCP_CFG_NO_INTERFACE,
161                            (NETCP_CFG_SA_T) globalDB.tx_sa[slot].saAppId,
162                             &error);
163             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
164                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
165                 globalDB.tx_sa[slot].saAppId, slot, error);
166         }
167     }
170 //void netTest_utilsStatsCb(NETAPI_T h, paSysStats_t* pPaStats)
171 NETAPI_SA_STATS_T netapi_sa_statsrx;
172 NETAPI_SA_STATS_T netapi_sa_statstx;
175 void printIPSecStats(Sa_IpsecStats_t* p_saIpsecStats,
176                      nwal_saAALG auth,
177                      nwal_saEALG cipher,
178                      uint32_t    saAppId)
181     printf("\n appId: 0x%x: Autentication mode: %d, Encryption Mode: %d\n",
182                 saAppId,
183                 auth,
184                 cipher);
185                 
186     printf("IPSec replayOld:0x%x,replayDup:0x%x,authFail:0x%x \n",
187                    p_saIpsecStats->replayOld,p_saIpsecStats->replayDup,p_saIpsecStats->authFail);
188     printf("IPSec txESN:0x%x,rxESN:0x%x,pktEncHi:0x%x,pktEncLo:0x%x,pktDecHi:0x%x,pktDecLo:0x%x \n",
189                    p_saIpsecStats->txESN,p_saIpsecStats->rxESN,p_saIpsecStats->pktEncHi,
190                    p_saIpsecStats->pktEncLo,p_saIpsecStats->pktDecHi,p_saIpsecStats->pktDecLo);
197 void utilsStatsCb(NETAPI_T h)
199     uint32_t numFreeDataPackets;
200     uint32_t            numZeroBufferPackets;
201     uint32_t            numPacketsinGarbage;
202     Pktlib_HeapStats    pktLibHeapStats;
203     int i,j;
208         if(globalDB.rx_sa[0].saAppId)
209         {
210             /* Statistics for RX Tunnel */
211             memset(&netapi_sa_statsrx, 0, sizeof(netapi_sa_statsrx));
212             netapi_getSaStats(netapi_handle,
213                               globalDB.rx_sa[0].saAppId,
214                               &netapi_sa_statsrx);
215             if (netapi_sa_statsrx.validParams & NETAPI_IPSEC_STAT_VALID)
216             {
217                 printIPSecStats(&netapi_sa_statsrx.saIpsecStats,
218                                  NWAL_SA_AALG_HMAC_SHA1,
219                                  NWAL_SA_EALG_AES_CBC,
220                                  globalDB.rx_sa[0].saAppId);
221             }
222         }
223 #if 1
224         if (globalDB.tx_sa[0].saAppId)
225         {
226             memset(&netapi_sa_statstx, 0, sizeof(netapi_sa_statstx));
227             netapi_getSaStats(netapi_handle,
228                               globalDB.tx_sa[0].saAppId,
229                               &netapi_sa_statstx);
230             if (netapi_sa_statstx.validParams & NETAPI_IPSEC_STAT_VALID)
231             {
232                  printIPSecStats(&netapi_sa_statstx.saIpsecStats,
233                                    NWAL_SA_AALG_HMAC_SHA1,
234                                    NWAL_SA_EALG_AES_CBC,
235                                    globalDB.tx_sa[0].saAppId);
236             }
237         }
238 #endif
240 static void* snoop_run_thread (void* arg)
242     cpu_set_t cpu_set;
243     CPU_ZERO( &cpu_set);
244     CPU_SET( 0, &cpu_set);
246     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
247     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
248         "snoop_run_thread: daemon entering forever event loop\n");
249     int count=0;
250     int sat=500000;
251     while (1)
252     {
253         /* Poll for message from user application */
254         ipsecmgr_ipc_poll();
256         /* Poll for message from Kernel */
257         ipsecmgr_snoop_run();
258 #if 1
259         if((count % 500000) == 0)
260             utilsStatsCb(netapi_handle);
261         
262 #endif
263         count++;
264         if (QUIT == 1)
265             break;
266     }
267     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
268         "snoop_run_thread: calling shutdown\n");
269     utilsStatsCb(netapi_handle);
270     ipsecmgr_snoop_shutdown ();
271     cleanup_sa_sp();
272     netapi_shutdown(netapi_handle);
274     return;
277 /**
278  *  @b Description
279  *  @n  
280  *      SIGTERM handler.
281  *
282  *  @param[in]  signum
283  *      signal number to terminate deamon.
284  */
285 static void sig_term_handler(int signum)
287     QUIT = 1;
290 /**
291  *  @b Description
292  *  @n  
293  *      Function to implement task sleep functionality 
294  *      for IPSecMgr
295  *
296  *  @param[in]  time_in_msec
297  *      Time in milliseconds to sleep
298  *
299  *  @retval
300  *      Not Applicable.
301  */
302 static void task_sleep(uint32_t time_in_msec)
304     pthread_mutex_t fake_mutex = PTHREAD_MUTEX_INITIALIZER;
305     pthread_cond_t fake_cond = PTHREAD_COND_INITIALIZER;
306     struct timespec ts;
307     int rt;
308     unsigned int sec, nsec;
310     sec = time_in_msec/1000;
311     nsec = (time_in_msec - (sec*1000)) * 1000000;
313     /* Use the wall-clock time */
314     clock_gettime(CLOCK_REALTIME, &ts);
316     ts.tv_sec += sec;
317     ts.tv_nsec += nsec;
319     pthread_mutex_lock(&fake_mutex);
320     rt = pthread_cond_timedwait(&fake_cond, &fake_mutex, &ts);
321     pthread_mutex_unlock(&fake_mutex);
325 /**
326  *  @b Description
327  *  @n  
328  *      NETAPI Proxy's IPSecMgr Start Offload Response 
329  *      message handler.
330  *
331  *      This function is called by the IPSecMgr library
332  *      when it has a response ready corresponding to an
333  *      Start Offload SP request issued by the user application.
334  *
335  *  @param[in]  rsp
336  *      IPSecMgr's Start Offload SP response
337  *  @param[in]  addr
338  *      Destination address (user application) to send 
339  *      the response to
340  *  @param[in]  addr_size
341  *      Size of destination address passed
342  *
343  *  @retval
344  *      Success -   0
345  *  @retval
346  *      ERROR   -   <0
347  */
348 static int offload_sp_rsp_send
350     ipsecmgr_snoop_offload_sp_rsp_param_t *rsp,
351     void                                  *addr,
352     uint32_t                              addr_size
355     ipsecmgr_ipc_offload_sp_rsp_param_t offload_sp_rsp;
357     offload_sp_rsp.type = rsp->type;
358     offload_sp_rsp.result = rsp->result;
359     offload_sp_rsp.trans_id = rsp->trans_id;
360     offload_sp_rsp.err_code = rsp->err_code;
361     offload_sp_rsp.sp_handle = rsp->sp_handle;
362     offload_sp_rsp.sa_handle = rsp->sa_handle;
364     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
365         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
366             "offload_sp_rsp_send: addr size not correct\n");
367         return -1;
368     }
370     return send_iface->offload_sp_rsp(&offload_sp_rsp,
371                                       (ipsecmgr_ipc_addr_t *)addr);
373 static void offload_sp_req_recv
375     ipsecmgr_ipc_offload_sp_req_param_t *req,
376     ipsecmgr_ipc_addr_t                 *src_addr
379     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"offload_sp_req_recv called for policy id\n",
380     req->policy_id);
381     ipsecmgr_snoop_offload_sp_rsp_param_t rsp;
382     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
383     ipsecmgr_snoop_offload_sp_req_param_t offload_sp_req;
385     offload_sp_req.trans_id = req->trans_id;
386     offload_sp_req.policy_id = req->policy_id;
387     offload_sp_req.sa_flags = req->sa_flags;
388     offload_sp_req.if_name = req->if_name;
389     offload_sp_req.dscp_cfg = req->dscp_cfg;
390     offload_sp_req.l5_selector = req->l5_selector;
392     memset(&rsp, 0, sizeof(rsp));
393     rsp.trans_id = req->trans_id;
395     if (ipsecmgr_snoop_offload_sp_req(&offload_sp_req, (void*)src_addr,
396                                       addr_size)) {
397         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
398             "offload_sp_req_recv: snoop_offload_sp_req failed\n");
399         rsp.result = RESULT_FAILURE;
400         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
401     }
402     else
403     {
404         rsp.result = RESULT_SUCCESS;
405         rsp.type = RSP_TYPE_ACK;
406     }
407     
408     if (offload_sp_rsp_send(&rsp, (void *)src_addr, addr_size))
409     {
410         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
411             "offload_sp_req_recv: failed to send ACK for offload_sp\n");
412     }
413     return;
417 /**
418  *  @b Description
419  *  @n  
420  *      NETAPI Proxy's IPSecMgr Stop Offload response message 
421  *      handler.
422  *
423  *      This function is called by the IPSecMgr library
424  *      when it has a response ready corresponding to an
425  *      Stop Offload SP request issued by the user application.
426  *
427  *  @param[in]  rsp
428  *      IPSecMgr's Stop Offload SP response
429  *  @param[in]  addr
430  *      Destination address (user application) to send 
431  *      the response to
432  *  @param[in]  addr_size
433  *      Size of destination address passed
434  *
435  *  @retval
436  *      Success -   0
437  *  @retval
438  *      ERROR   -   <0
439  */
440 static int stop_offload_rsp_send
442     ipsecmgr_snoop_stop_offload_rsp_param_t *rsp,
443     void                                    *addr,
444     uint32_t                                addr_size
447     ipsecmgr_ipc_stop_offload_rsp_param_t stop_offload_rsp;
449     stop_offload_rsp.type = rsp->type;
450     stop_offload_rsp.result = rsp->result;
451     stop_offload_rsp.trans_id = rsp->trans_id;
453     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
454         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
455             "stop_offload_rsp_send: addr size not correct\n");
456         return -1;
457     }
459     return send_iface->stop_offload_rsp(&stop_offload_rsp,
460                                       (ipsecmgr_ipc_addr_t *)addr);
463 static void stop_offload_req_recv
465     ipsecmgr_ipc_stop_offload_req_param_t   *req,
466     ipsecmgr_ipc_addr_t                     *src_addr
469     ipsecmgr_snoop_stop_offload_req_param_t stop_offload_req;
470     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
471     ipsecmgr_snoop_stop_offload_rsp_param_t rsp;
473     stop_offload_req.trans_id = req->trans_id;
474     stop_offload_req.policy_id = req->policy_id;
476     memset(&rsp, 0, sizeof(rsp));
477     rsp.trans_id = req->trans_id;
479     if (ipsecmgr_snoop_stop_offload(&stop_offload_req, (void*)src_addr,
480                                       addr_size)) {
481         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
482             "stop_offload_req_recv: snoop_stop_offload failed\n");
483         rsp.result = RESULT_FAILURE;
484         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
485     }
486     else
487     {
488         rsp.result = RESULT_SUCCESS;
489         rsp.type = RSP_TYPE_ACK;
490     }
492     if (stop_offload_rsp_send(&rsp, (void *)src_addr, addr_size))
493     {
494         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
495             "stop_offload_req_recv: failed to send ACK for stop_offload\n");
496     }
497     return;
500 /**
501  *  @b Description
502  *  @n  
503  *      Function to initialize IPSec Manager library.
504  *
505  *  @retval
506  *      Success -   0
507  *  @retval
508  *      ERROR   -   >0
509  */
510 static int32_t init_ipsecmgr (void)
512     struct ipsecmgr_snoop_fp_cfg_cb     fp_cfg_cb;
513     struct ipsecmgr_snoop_mgnt_cb       mgnt_cb;
514     struct ipsecmgr_snoop_platform_cb   plat_cb;
515     ipsecmgr_ipc_daemon_recv_if_t       recv_if;
516     ipsecmgr_ipc_cfg_t                  ipc_cfg;
517     int32_t                             status;
518     pthread_attr_t threadAttr;
520     /* Initializations */
521     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, 
522                         "DEBUG: init_ipsecmgr() starting initialization\n");
523     memset(&fp_cfg_cb, 0, sizeof(fp_cfg_cb));
524     memset(&mgnt_cb, 0, sizeof(mgnt_cb));
525     memset(&plat_cb, 0, sizeof(plat_cb));
526     memset(&recv_if, 0, sizeof(recv_if));
527     memset(&ipc_cfg, 0, sizeof(ipc_cfg));
529     /* Initialize IPC library */
530     ipc_cfg.mode = IPC_MODE_SNOOP_DAEMON;
531     if (ipsecmgr_ipc_init(&ipc_cfg)) {
532         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
533             "init_ipsecmgr: ipc_init failed\n");
534         return -1;
535     }
536     else
537         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
538             "init_ipsecmgr: ipc_init sucess\n");
540     if (ipsecmgr_ipc_get_daemon_send_iface(&send_iface)) {
541         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
542             "init_ipsecmgr: ipc_get_daemon_send_iface failed\n");
543         return -1;
544     }
545     recv_if.offload_sp_req = offload_sp_req_recv;
546     recv_if.stop_offload_req = stop_offload_req_recv;
547     /* Register ipsecmgr daemon recieve i/f */
548     if (ipsecmgr_ipc_register_daemon_recv_iface(&recv_if)) {
549         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
550             "snoop_run: ipc_register_daemon_recv_iface failed\n");
551         return -1;
552     }
554     /* Initialize the IPSec Manager Snoop library */
555     fp_cfg_cb.add_sa        =   netapilib_ifAddSA;
556     fp_cfg_cb.add_sp        =   netapilib_ifAddSP;
557     fp_cfg_cb.del_sa        =   netapilib_ifDeleteSA;
558     fp_cfg_cb.del_sp        =   netapilib_ifDeleteSP;
559     fp_cfg_cb.get_sa_ctx    =   netapilib_ifGetSACtx;
561     plat_cb.log_msg  = (ipsecmgr_snoop_log_msg_t)ipsecmgr_syslog_msg;
562     plat_cb.sleep           =   task_sleep;
564     mgnt_cb.offload_sp_rsp  =   offload_sp_rsp_send;
565     mgnt_cb.stop_offload_rsp=   stop_offload_rsp_send;
566     mgnt_cb.rekey_event     =   NULL; // No explicit notifications needed on Rekey completion
568     if ((status = ipsecmgr_snoop_init (&fp_cfg_cb, &mgnt_cb, &plat_cb))) 
569     {
570         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
571                             "DEBUG: init_ipsecmgr() ipsecmgr_snoop_init failed (%d)\n", status);
572         return -1;
573     }
577 #ifdef GDB_DEBUG
578     snoop_run_thread(NULL);
579 #else
580     /* Create the task context for snoop library */
581     pthread_attr_init(&threadAttr);
582     pthread_attr_setstacksize(&threadAttr, 0x10000);
583     if (pthread_create(&snoop_run_th, (void*) NULL, snoop_run_thread, NULL))
584     {
585         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
586             "ERROR: snoop run thread failed to start, error code\n"); 
587         return -1;
588     }
590     /* Setup signal handler for SIGTERM */
591     if (signal(SIGTERM, sig_term_handler) == SIG_ERR) {
592         ipsecmgr_syslog_msg(SYSLOG_LEVEL_WARN,
593             "init_ipsecmgr: cannot handle SIGTERM\n");
594     }
595     /* Wait for the NETAPI Proxy task to finish its processing and exit. */
596     pthread_join (snoop_run_th, NULL);
597 #endif
598     return 0;
601 /**
602  *  @b Description
603  *  @n  
604  *      Utility function to daemonize the current
605  *      application.
606  *
607  *  @param[in]  lock_file
608  *      Lock file to be used by the daemon
609  */
610 static void daemonize (const char *lock_file)
612     pid_t       pid, sid;
613     int32_t     lock_fp = -1;
614     char        str[10];
616     /* already a daemon */
617     if (getppid () == 1)
618         return;
620     /* Fork off the parent process */
621     if ((pid = fork ()) < 0) 
622     {
623         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
624                             "ERROR: daemonize() unable to fork daemon, code=%d (%s)",
625                             errno, 
626                             strerror(errno));
627         exit (-1);
628     }
630     /* If we got a PID, then exit the parent process. */
631     if (pid > 0)
632         exit (0);
634     /* At this point we are executing as the child process */
636     /* Create a new SID for the child process */
637     if ((sid = setsid ()) < 0) 
638     {
639         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
640                             "ERROR: daemonize() unable to create a new session, code %d (%s)",
641                             errno, 
642                             strerror(errno));
643         exit (-1);
644     }
646     /* Change the file mode mask */
647     umask (027);
649     /* Change the current working directory.  This prevents the current
650      * directory from being locked; hence not being able to remove it. */
651     if ((chdir("/")) < 0) 
652     {
653         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
654                             "ERROR: daemonize() unable to change directory to %s, code %d (%s)",
655                             "/", 
656                             errno, 
657                             strerror(errno));
658         exit (-1);
659     }
661     /* Create the lock file */
662     if (lock_file) 
663     {
664         if ((lock_fp = open(lock_file, O_RDWR|O_CREAT, 0640)) < 0 ) 
665         {
666             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
667                                 "ERROR: daemonize() unable to create lock file %s, code=%d (%s)",
668                                 lock_file, 
669                                 errno, 
670                                 strerror(errno));
671             exit (-1);
672         }
673     }
675     if (lockf (lock_fp, F_TLOCK, 0) < 0) 
676         exit(-1); /* can not lock */
678     /* Record pid to lockfile */
679     sprintf (str, "%d\n", getpid());
680     write (lock_fp, str, strlen(str)); 
682     /* Cancel certain signals */
683     signal (SIGCHLD, SIG_DFL); /* A child process dies */
684     signal (SIGTSTP, SIG_IGN); /* Various TTY signals */
685     signal (SIGTTOU, SIG_IGN);
686     signal (SIGTTIN, SIG_IGN);
687     signal (SIGHUP, SIG_IGN); /* Ignore hangup signal */
688     signal (SIGTERM, sig_term_handler); /* catch SIGTERM */
690     /* Redirect standard files to /dev/null */
691     freopen( "/dev/null", "r", stdin);
692     freopen( "/dev/null", "w", stdout);
693     freopen( "/dev/null", "w", stderr);
695     /* Done setting up the daemon */
696     return;
699 int get_kernel_config()
701     uint32_t temp=0;
702     FILE *pDts = NULL;
704     pDts = fopen(DTS_LOG_FILE_QUEUE_ETHx[0], "rb");
706     if(pDts)
707     {
708         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
709         globalDB.qNum = (int)swap32(temp);
710         fclose(pDts);
711     }
712     else
713     {
714         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
715             "main: error opening device tree file: %s\n",DTS_LOG_FILE_QUEUE_ETHx[0]);
716         return -1;
717     }
719     pDts = NULL;
720     pDts = fopen(DTS_LOG_FILE_FLOW_ETHx[0], "rb");
722     if(pDts)
723     {
724         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
725         globalDB.flowId = (int)swap32(temp);
726         fclose(pDts);
727     }
728     else
729     {
730         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
731             "main: error opening device tree file: %s\n",DTS_LOG_FILE_FLOW_ETHx[0]);
732         return -1;
733     }
734     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
735             "get_kernel_config: flow: 0x%x, qNum: 0x%x\n", 
736              globalDB.flowId, globalDB.qNum);
737     return 0;
740 int create_pktio_channel()
742     static int count = 0;
743     int error = 0;
744     char name[19];
745     PKTIO_HANDLE_T *pktio_channel;
746     PKTIO_CFG_T pktio_cfg;
747     NETCP_CFG_ROUTE_T route;
748     NETCP_CFG_FLOW_T flow;
749     NETCP_CFG_EXCEPTION_PKT_T expPkt_appid = 0;
751     memset(&pktio_cfg,0,sizeof(PKTIO_CFG_T));
752     memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
753     memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
755     sprintf(&name[0],"%s","offload_0");
756     pktio_cfg.qnum = globalDB.qNum;
757     pktio_cfg.flags1 = PKTIO_RX;
758     pktio_cfg.flags2 = PKTIO_GLOBAL | PKTIO_PKT;
759     pktio_cfg.max_n = 8;
761     globalDB.pktio_channel = netapi_pktioCreate(netapi_handle,
762                                                &name[0],
763                                                (PKTIO_CB)recv_cb,
764                                                &pktio_cfg,
765                                                &error);
766     if (!globalDB.pktio_channel)
767     {
768         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
769             "create_pktio_channel: failed\n");
770         return -1;
771     }
773     printf("create_pktio_channel: qnum: %d, pktio_handle: 0x%x\n",
774             pktio_cfg.qnum,
775             globalDB.pktio_channel);
777     flow.dma_engine= 1;
778     flow.flowid = globalDB.flowId;
779     route.p_dest_q = globalDB.pktio_channel;
780     route.p_flow = &flow;
781     route.valid_params |= NETCP_CFG_VALID_PARAM_ROUTE_TYPE;
782     route.routeType = NWAL_ROUTE_RX_INTF_W_FLOW;
783     /* enable exception packet handling for fragmented packets */
784     expPkt_appid = netapi_netcpCfgExceptions(netapi_handle,
785                                              7,
786                                              NETCP_CFG_ACTION_TO_SW,
787                                              (NETCP_CFG_ROUTE_HANDLE_T) &route);
788     printf("create_pktio_channel: expPkt appid: 0x%x\n", expPkt_appid);
790     return 0;
792 /**
793  *  @b Description
794  *  @n  
795  *      Entry point for the NETAPI Proxy application.
796  *
797  *  @param[in]  argc
798  *      Number of arguments passed to the application
799  *  @param[in]  argv
800  *      Arguments passed to the application.
801  *
802  *  @retval
803  *      Success -   0
804  *  @retval
805  *      ERROR   -   >0
806  */
807 int32_t main (int argc, char* argv[])
809     int32_t             retVal;
810     int i, iface;
811     char* pTok = NULL;
812     int ip_entry_count = 0;
813     struct ifaddrs *ifaddr, *ifa;
814     int family, s;
815     char host[NI_MAXHOST];
816     struct sockaddr_in6 ipv6_addr;
817     cpu_set_t cpu_set;
818     ipsecmgr_syslog_init();
820     memset(&globalDB, 0, sizeof(globalDB));
822     /* assign main net_test thread to run on core 0 */
823     CPU_ZERO( &cpu_set);
824     CPU_SET( 0, &cpu_set);
825     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
826     /* create netapi */
827     netapi_handle = netapi_init(NETAPI_SYS_MASTER,
828                                 &our_netapi_default_cfg);
829     if(netapi_handle == NULL)
830     {
831         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
832                              "ERROR: netapi_init failed\n");
833         return -1;
834     }
835     else
836         netapi_netcpCfgExceptions(netapi_handle,
837                                   NETCP_CFG_ALL_EXCEPTIONS,
838                                   NETCP_CFG_ACTION_DISCARD,
839                                   (NETCP_CFG_ROUTE_HANDLE_T) NULL);
841     if (get_kernel_config())
842     {
843         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
844                             "ERROR: main: get_kernel_config() failed\n");
845         return -1;
846     }
847     else
848     {
849         /* create pktio channel */
850         if(create_pktio_channel())
851         {
852             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
853                             "ERROR: main: pktio channel creation failed\n");
854             return -1;
855         }
856     }
857      /*Create the proxy daemon. */
858     printf("main: calling daemonize\n");
859     daemonize (LOCK_FILE); 
861     /* Initialize and start the IPSec Mgr Snoop functionality */
862     if ((retVal = init_ipsecmgr ()) < 0)
863     {
864         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
865                             "ERROR: IPSec Mgr init failed, error code %d \n",
866                             retVal);
867         return -1;
868     }
869     else
870         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
871                              "main: ipsecmgr daemon shutdonw complete\n");