Resolve NETAPI library coverity warnings.
[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 #if defined(DEVICE_K2H)
64 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
65 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
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"};
70 #elif defined (DEVICE_K2K)
71 #include <ti/drv/qmss/device/k2k/src/qmss_device.c>
72 #include <ti/drv/cppi/device/k2k/src/cppi_device.c>
73 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
74  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
75 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
76 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
77 #elif defined (DEVICE_K2L)
78 #include <ti/drv/qmss/device/k2l/src/qmss_device.c>
79 #include <ti/drv/cppi/device/k2l/src/cppi_device.c>
80 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
81  "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/complete-queue"};
82 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
83 "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/flow"};
84 #elif defined (DEVICE_K2E)
85 #include <ti/drv/qmss/device/k2e/src/qmss_device.c>
86 #include <ti/drv/cppi/device/k2e/src/cppi_device.c>
87 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
88  "/proc/device-tree/soc/pktdma@24186000/channels/netrx0/complete-queue"};
89 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
90 "/proc/device-tree/soc/pktdma@24186000/channels/netrx0/flow"};
92 #else /*Default */
93 #include <ti/runtime/hplib/device/k2h/src/hplib_device.c>
94 #include <ti/runtime/netapi/device/k2h/src/netapi_device.c>
95 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
96 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
97 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
98  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
99 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
100 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
102 #endif
104 /**********************************************************************
105  ************************** Local Definitions *************************
106  **********************************************************************/
107 #if 0
109 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
110  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
111 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
112 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
114 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
115  "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/complete-queue"};
116 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
117 "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/flow"};
118 #endif
121 /**********************************************************************
122  ************************** Global Variables **************************
123  **********************************************************************/
124 extern Rm_ServiceHandle   *rmClientServiceHandle;
126 static ipsecmgr_ipc_daemon_send_if_t *send_iface;
127 NETAPI_T netapi_handle;
129 ipsecMgrMcb_t globalDB;
131 static int use_rm =0;
133 /* Lock file for the daemon */
134 #define LOCK_FILE   "/var/lock/ipsecmgr_daemon"
136 /* snoop task */
137 static pthread_t    snoop_run_th;
139 static NETAPI_CFG_T our_netapi_default_cfg=
141     TUNE_NETAPI_PERM_MEM_SZ,
142     128,  //start of packet offset for hw to place data on rx for default flow
143     TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
144     TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
145     TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
146     64, //#descriptors w/o buffers in default heap
147     TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
148     128,    //tail room
149     256,    //extra room
150     0,
151     NULL
152 };
156 static int QUIT = 0;
158 /* stub functions */
159 static void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
160                          PKTIO_METADATA_T meta[], int n_pkts,
161                          uint64_t ts )
163     return;
166 /* byte swap routine */
167 static unsigned int swap32 (unsigned int x)
169     unsigned int y;
171     y = (((x >> 24) & 0xff) <<  0) |
172         (((x >> 16) & 0xff) <<  8) |
173         (((x >>  8) & 0xff) << 16) |
174         (((x >>  0) & 0xff) << 24) ;
176     return (y);
180 void cleanup_sa_sp()
182     int slot, error=0;;
183     /* delete any offloaded rx SA's and policies */
184     /* and delete any offloaded tx SA's */
185     for (slot = 0;slot < 64;slot++)
186     {
187         if(globalDB.rx_sa[slot].in_use)
188         {
189             globalDB.rx_sa[slot].in_use = 0;
190             if(globalDB.rx_sa[slot].spAppId)
191             {
192                 netapi_secDelRxPolicy(netapi_handle,
193                               (NETCP_CFG_IPSEC_POLICY_T) globalDB.rx_sa[slot].spAppId,
194                               &error);
195                 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
196                 "cleanup_sa_sp: SP deleted: sp_app_id: 0x%x, slot: %d, error: %d\n", 
197                 globalDB.rx_sa[slot].spAppId, slot, error);
198             }
199             netapi_secDelSA(netapi_handle,
200                         NETCP_CFG_NO_INTERFACE,
201                         (NETCP_CFG_SA_T) globalDB.rx_sa[slot].saAppId,
202                         &error);
203             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
204                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
205                 globalDB.rx_sa[slot].saAppId, slot, error);
206             
207         }
208         if(globalDB.tx_sa[slot].in_use)
209         {
210             globalDB.tx_sa[slot].in_use = 0;
211             netapi_secDelSA(netapi_handle,
212                             NETCP_CFG_NO_INTERFACE,
213                            (NETCP_CFG_SA_T) globalDB.tx_sa[slot].saAppId,
214                             &error);
215             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
216                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
217                 globalDB.tx_sa[slot].saAppId, slot, error);
218         }
219     }
223 static void* snoop_run_thread (void* arg)
225     cpu_set_t cpu_set;
226     CPU_ZERO( &cpu_set);
227     CPU_SET( 0, &cpu_set);
229     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
230     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
231         "snoop_run_thread: daemon entering forever event loop\n");
233     while (1)
234     {
235         /* Poll for message from user application */
236         ipsecmgr_ipc_poll();
238         /* Poll for message from Kernel */
239         ipsecmgr_snoop_run();
240         if (QUIT == 1)
241             break;
242     }
243     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
244         "snoop_run_thread: calling shutdown\n");
245     ipsecmgr_snoop_shutdown ();
246     cleanup_sa_sp();
247     netapi_shutdown(netapi_handle);
249     if (use_rm)
250         closeRm();
251     return ((void*)NULL);
254 /**
255  *  @b Description
256  *  @n  
257  *      SIGTERM handler.
258  *
259  *  @param[in]  signum
260  *      signal number to terminate deamon.
261  */
262 static void sig_term_handler(int signum)
264     QUIT = 1;
267 /**
268  *  @b Description
269  *  @n  
270  *      Function to implement task sleep functionality 
271  *      for IPSecMgr
272  *
273  *  @param[in]  time_in_msec
274  *      Time in milliseconds to sleep
275  *
276  *  @retval
277  *      Not Applicable.
278  */
279 static void task_sleep(uint32_t time_in_msec)
281     pthread_mutex_t fake_mutex = PTHREAD_MUTEX_INITIALIZER;
282     pthread_cond_t fake_cond = PTHREAD_COND_INITIALIZER;
283     struct timespec ts;
284     int rt;
285     unsigned int sec, nsec;
287     sec = time_in_msec/1000;
288     nsec = (time_in_msec - (sec*1000)) * 1000000;
290     /* Use the wall-clock time */
291     clock_gettime(CLOCK_REALTIME, &ts);
293     ts.tv_sec += sec;
294     ts.tv_nsec += nsec;
296     pthread_mutex_lock(&fake_mutex);
297     rt = pthread_cond_timedwait(&fake_cond, &fake_mutex, &ts);
298     pthread_mutex_unlock(&fake_mutex);
302 /**
303  *  @b Description
304  *  @n  
305  *      NETAPI Proxy's IPSecMgr Start Offload Response 
306  *      message handler.
307  *
308  *      This function is called by the IPSecMgr library
309  *      when it has a response ready corresponding to an
310  *      Start Offload SP request issued by the user application.
311  *
312  *  @param[in]  rsp
313  *      IPSecMgr's Start Offload SP response
314  *  @param[in]  addr
315  *      Destination address (user application) to send 
316  *      the response to
317  *  @param[in]  addr_size
318  *      Size of destination address passed
319  *
320  *  @retval
321  *      Success -   0
322  *  @retval
323  *      ERROR   -   <0
324  */
325 static int offload_sp_rsp_send
327     ipsecmgr_snoop_offload_sp_rsp_param_t *rsp,
328     void                                  *addr,
329     uint32_t                              addr_size
332     ipsecmgr_ipc_offload_sp_rsp_param_t offload_sp_rsp;
334     offload_sp_rsp.type = rsp->type;
335     offload_sp_rsp.result = rsp->result;
336     offload_sp_rsp.trans_id = rsp->trans_id;
337     offload_sp_rsp.err_code = rsp->err_code;
338     offload_sp_rsp.sp_handle = rsp->sp_handle;
339     offload_sp_rsp.sa_handle = rsp->sa_handle;
341     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
342         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
343             "offload_sp_rsp_send: addr size not correct\n");
344         return -1;
345     }
347     return send_iface->offload_sp_rsp(&offload_sp_rsp,
348                                       (ipsecmgr_ipc_addr_t *)addr);
350 static void offload_sp_req_recv
352     ipsecmgr_ipc_offload_sp_req_param_t *req,
353     ipsecmgr_ipc_addr_t                 *src_addr
356     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"offload_sp_req_recv called for policy id\n",
357     req->policy_id);
358     ipsecmgr_snoop_offload_sp_rsp_param_t rsp;
359     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
360     ipsecmgr_snoop_offload_sp_req_param_t offload_sp_req;
362     offload_sp_req.trans_id = req->trans_id;
363     offload_sp_req.policy_id = req->policy_id;
364     offload_sp_req.sa_flags = req->sa_flags;
365     offload_sp_req.if_name = req->if_name;
366     offload_sp_req.dscp_cfg = req->dscp_cfg;
367     offload_sp_req.l5_selector = req->l5_selector;
368     //offload_sp_req.oseq_offset = req->oseq_offset;
370     memset(&rsp, 0, sizeof(rsp));
371     rsp.trans_id = req->trans_id;
373     if (ipsecmgr_snoop_offload_sp_req(&offload_sp_req, (void*)src_addr,
374                                       addr_size)) {
375         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
376             "offload_sp_req_recv: snoop_offload_sp_req failed\n");
377         rsp.result = RESULT_FAILURE;
378         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
379     }
380     else
381     {
382         rsp.result = RESULT_SUCCESS;
383         rsp.type = RSP_TYPE_ACK;
384     }
385     
386     if (offload_sp_rsp_send(&rsp, (void *)src_addr, addr_size))
387     {
388         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
389             "offload_sp_req_recv: failed to send ACK for offload_sp\n");
390     }
391     return;
395 /**
396  *  @b Description
397  *  @n  
398  *      NETAPI Proxy's IPSecMgr Stop Offload response message 
399  *      handler.
400  *
401  *      This function is called by the IPSecMgr library
402  *      when it has a response ready corresponding to an
403  *      Stop Offload SP request issued by the user application.
404  *
405  *  @param[in]  rsp
406  *      IPSecMgr's Stop Offload SP response
407  *  @param[in]  addr
408  *      Destination address (user application) to send 
409  *      the response to
410  *  @param[in]  addr_size
411  *      Size of destination address passed
412  *
413  *  @retval
414  *      Success -   0
415  *  @retval
416  *      ERROR   -   <0
417  */
418 static int stop_offload_rsp_send
420     ipsecmgr_snoop_stop_offload_rsp_param_t *rsp,
421     void                                    *addr,
422     uint32_t                                addr_size
425     ipsecmgr_ipc_stop_offload_rsp_param_t stop_offload_rsp;
427     stop_offload_rsp.type = rsp->type;
428     stop_offload_rsp.result = rsp->result;
429     stop_offload_rsp.trans_id = rsp->trans_id;
431     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
432         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
433             "stop_offload_rsp_send: addr size not correct\n");
434         return -1;
435     }
437     return send_iface->stop_offload_rsp(&stop_offload_rsp,
438                                       (ipsecmgr_ipc_addr_t *)addr);
441 static void stop_offload_req_recv
443     ipsecmgr_ipc_stop_offload_req_param_t   *req,
444     ipsecmgr_ipc_addr_t                     *src_addr
447     ipsecmgr_snoop_stop_offload_req_param_t stop_offload_req;
448     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
449     ipsecmgr_snoop_stop_offload_rsp_param_t rsp;
451     stop_offload_req.trans_id = req->trans_id;
452     stop_offload_req.policy_id = req->policy_id;
454     memset(&rsp, 0, sizeof(rsp));
455     rsp.trans_id = req->trans_id;
457     if (ipsecmgr_snoop_stop_offload(&stop_offload_req, (void*)src_addr,
458                                       addr_size)) {
459         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
460             "stop_offload_req_recv: snoop_stop_offload failed\n");
461         rsp.result = RESULT_FAILURE;
462         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
463     }
464     else
465     {
466         rsp.result = RESULT_SUCCESS;
467         rsp.type = RSP_TYPE_ACK;
468     }
470     if (stop_offload_rsp_send(&rsp, (void *)src_addr, addr_size))
471     {
472         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
473             "stop_offload_req_recv: failed to send ACK for stop_offload\n");
474     }
475     return;
478 /**
479  *  @b Description
480  *  @n  
481  *      Function to initialize IPSec Manager library.
482  *
483  *  @retval
484  *      Success -   0
485  *  @retval
486  *      ERROR   -   >0
487  */
488 static int32_t init_ipsecmgr (void)
490     struct ipsecmgr_snoop_fp_cfg_cb     fp_cfg_cb;
491     struct ipsecmgr_snoop_mgnt_cb       mgnt_cb;
492     struct ipsecmgr_snoop_platform_cb   plat_cb;
493     ipsecmgr_ipc_daemon_recv_if_t       recv_if;
494     ipsecmgr_ipc_cfg_t                  ipc_cfg;
495     int32_t                             status;
496     pthread_attr_t threadAttr;
498     /* Initializations */
499     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, 
500                         "DEBUG: init_ipsecmgr() starting initialization\n");
501     memset(&fp_cfg_cb, 0, sizeof(fp_cfg_cb));
502     memset(&mgnt_cb, 0, sizeof(mgnt_cb));
503     memset(&plat_cb, 0, sizeof(plat_cb));
504     memset(&recv_if, 0, sizeof(recv_if));
505     memset(&ipc_cfg, 0, sizeof(ipc_cfg));
507     /* Initialize IPC library */
508     ipc_cfg.mode = IPC_MODE_SNOOP_DAEMON;
509     if (ipsecmgr_ipc_init(&ipc_cfg)) {
510         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
511             "init_ipsecmgr: ipc_init failed\n");
512         return -1;
513     }
514     else
515         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
516             "init_ipsecmgr: ipc_init sucess\n");
518     if (ipsecmgr_ipc_get_daemon_send_iface(&send_iface)) {
519         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
520             "init_ipsecmgr: ipc_get_daemon_send_iface failed\n");
521         return -1;
522     }
523     recv_if.offload_sp_req = offload_sp_req_recv;
524     recv_if.stop_offload_req = stop_offload_req_recv;
525     /* Register ipsecmgr daemon recieve i/f */
526     if (ipsecmgr_ipc_register_daemon_recv_iface(&recv_if)) {
527         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
528             "snoop_run: ipc_register_daemon_recv_iface failed\n");
529         return -1;
530     }
532     /* Initialize the IPSec Manager Snoop library */
533     fp_cfg_cb.add_sa        =   netapilib_ifAddSA;
534     fp_cfg_cb.add_sp        =   netapilib_ifAddSP;
535     fp_cfg_cb.del_sa        =   netapilib_ifDeleteSA;
536     fp_cfg_cb.del_sp        =   netapilib_ifDeleteSP;
537     fp_cfg_cb.get_sa_ctx    =   netapilib_ifGetSACtx;
539     plat_cb.log_msg  = (ipsecmgr_snoop_log_msg_t)ipsecmgr_syslog_msg;
540     plat_cb.sleep           =   task_sleep;
542     mgnt_cb.offload_sp_rsp  =   offload_sp_rsp_send;
543     mgnt_cb.stop_offload_rsp=   stop_offload_rsp_send;
544     mgnt_cb.rekey_event     =   NULL; // No explicit notifications needed on Rekey completion
546     if ((status = ipsecmgr_snoop_init (&fp_cfg_cb, &mgnt_cb, &plat_cb))) 
547     {
548         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
549                             "DEBUG: init_ipsecmgr() ipsecmgr_snoop_init failed (%d)\n", status);
550         return -1;
551     }
555 #ifdef GDB_DEBUG
556     snoop_run_thread(NULL);
557 #else
558     /* Create the task context for snoop library */
559     pthread_attr_init(&threadAttr);
560     pthread_attr_setstacksize(&threadAttr, 0x10000);
561     if (pthread_create(&snoop_run_th, (void*) NULL, snoop_run_thread, NULL))
562     {
563         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
564             "ERROR: snoop run thread failed to start, error code\n"); 
565         return -1;
566     }
568     /* Setup signal handler for SIGTERM */
569     if (signal(SIGTERM, sig_term_handler) == SIG_ERR) {
570         ipsecmgr_syslog_msg(SYSLOG_LEVEL_WARN,
571             "init_ipsecmgr: cannot handle SIGTERM\n");
572     }
573     /* Wait for the NETAPI Proxy task to finish its processing and exit. */
574     pthread_join (snoop_run_th, NULL);
575 #endif
576     return 0;
579 /**
580  *  @b Description
581  *  @n  
582  *      Utility function to daemonize the current
583  *      application.
584  *
585  *  @param[in]  lock_file
586  *      Lock file to be used by the daemon
587  */
588 static void daemonize (const char *lock_file)
590     pid_t       pid, sid;
591     int32_t     lock_fp = -1;
592     char        str[10];
594     /* already a daemon */
595     if (getppid () == 1)
596         return;
598     /* Fork off the parent process */
599     if ((pid = fork ()) < 0) 
600     {
601         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
602                             "ERROR: daemonize() unable to fork daemon, code=%d (%s)",
603                             errno, 
604                             strerror(errno));
605         exit (-1);
606     }
608     /* If we got a PID, then exit the parent process. */
609     if (pid > 0)
610         exit (0);
612     /* At this point we are executing as the child process */
614     /* Create a new SID for the child process */
615     if ((sid = setsid ()) < 0) 
616     {
617         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
618                             "ERROR: daemonize() unable to create a new session, code %d (%s)",
619                             errno, 
620                             strerror(errno));
621         exit (-1);
622     }
624     /* Change the file mode mask */
625     umask (027);
627     /* Change the current working directory.  This prevents the current
628      * directory from being locked; hence not being able to remove it. */
629     if ((chdir("/")) < 0) 
630     {
631         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
632                             "ERROR: daemonize() unable to change directory to %s, code %d (%s)",
633                             "/", 
634                             errno, 
635                             strerror(errno));
636         exit (-1);
637     }
639     /* Create the lock file */
640     if (lock_file) 
641     {
642         if ((lock_fp = open(lock_file, O_RDWR|O_CREAT, 0640)) < 0 ) 
643         {
644             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
645                                 "ERROR: daemonize() unable to create lock file %s, code=%d (%s)",
646                                 lock_file, 
647                                 errno, 
648                                 strerror(errno));
649             exit (-1);
650         }
651     
653         if (lockf (lock_fp, F_TLOCK, 0) < 0) 
654             exit(-1); /* can not lock */
656         /* Record pid to lockfile */
657         snprintf (str, 10,"%d\n", getpid());
658         write (lock_fp, str, strlen(str));
659         close(lock_fp);
660     }
661     /* Cancel certain signals */
662     signal (SIGCHLD, SIG_DFL); /* A child process dies */
663     signal (SIGTSTP, SIG_IGN); /* Various TTY signals */
664     signal (SIGTTOU, SIG_IGN);
665     signal (SIGTTIN, SIG_IGN);
666     signal (SIGHUP, SIG_IGN); /* Ignore hangup signal */
667     signal (SIGTERM, sig_term_handler); /* catch SIGTERM */
669     /* Redirect standard files to /dev/null */
670     freopen( "/dev/null", "r", stdin);
671     freopen( "/dev/null", "w", stdout);
672     freopen( "/dev/null", "w", stderr);
674     /* Done setting up the daemon */
675     return;
678 int get_kernel_config()
680     uint32_t temp=0;
681     FILE *pDts = NULL;
683     pDts = fopen(DTS_LOG_FILE_QUEUE_ETHx[0], "rb");
685     if(pDts)
686     {
687         if(fread((void*)&temp, sizeof(uint32_t), 1, pDts))
688         {
689             globalDB.qNum = (int)swap32(temp);
690         }
691         fclose(pDts);
692     }
693     else
694     {
695         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
696             "main: error opening device tree file: %s\n",DTS_LOG_FILE_QUEUE_ETHx[0]);
697         return -1;
698     }
700     pDts = NULL;
701     pDts = fopen(DTS_LOG_FILE_FLOW_ETHx[0], "rb");
703     if(pDts)
704     {
705         if (fread((void*)&temp, sizeof(uint32_t), 1, pDts))
706         {
707             globalDB.flowId = (int)swap32(temp);
708         }
709         fclose(pDts);
710     }
711     else
712     {
713         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
714             "main: error opening device tree file: %s\n",DTS_LOG_FILE_FLOW_ETHx[0]);
715         return -1;
716     }
717     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
718             "get_kernel_config: flow: 0x%x, qNum: 0x%x\n", 
719              globalDB.flowId, globalDB.qNum);
720     return 0;
723 int create_pktio_channel()
725     static int count = 0;
726     int error = 0;
727     char name[19];
728     PKTIO_HANDLE_T *pktio_channel;
729     PKTIO_CFG_T pktio_cfg;
730     NETCP_CFG_ROUTE_T route;
731     NETCP_CFG_FLOW_T flow;
732     NETCP_CFG_EXCEPTION_PKT_T expPkt_appid = 0;
734     memset(&pktio_cfg,0,sizeof(PKTIO_CFG_T));
735     memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
736     memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
738     snprintf(&name[0],PKTIO_MAX_NAME, "%s","offload_0");
739     pktio_cfg.qnum = globalDB.qNum;
740     pktio_cfg.flags1 = PKTIO_RX;
741     pktio_cfg.flags2 = PKTIO_GLOBAL | PKTIO_PKT;
742     pktio_cfg.max_n = 8;
743     pktio_cfg.queueType = Qmss_QueueType_GIC400_QUEUE;
745     globalDB.pktio_channel = netapi_pktioCreate(netapi_handle,
746                                                &name[0],
747                                                (PKTIO_CB)recv_cb,
748                                                &pktio_cfg,
749                                                &error);
750     if (!globalDB.pktio_channel)
751     {
752         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
753             "create_pktio_channel: failed\n");
754         return -1;
755     }
758     flow.dma_engine= 1;
759     flow.flowid = globalDB.flowId;
760     route.p_dest_q = globalDB.pktio_channel;
761     route.p_flow = &flow;
762     route.valid_params |= NETCP_CFG_VALID_PARAM_ROUTE_TYPE;
763     route.routeType = NWAL_ROUTE_RX_INTF_W_FLOW;
764     /* enable exception packet handling for fragmented packets */
765     expPkt_appid = netapi_netcpCfgExceptions(netapi_handle,
766                                              7,
767                                              NETCP_CFG_ACTION_TO_SW,
768                                              (NETCP_CFG_ROUTE_HANDLE_T) &route);
770     return 0;
772 /**
773  *  @b Description
774  *  @n  
775  *      Entry point for the NETAPI Proxy application.
776  *
777  *  @param[in]  argc
778  *      Number of arguments passed to the application
779  *  @param[in]  argv
780  *      Arguments passed to the application.
781  *
782  *  @retval
783  *      Success -   0
784  *  @retval
785  *      ERROR   -   >0
786  */
787 int32_t main (int argc, char* argv[])
789     int32_t             retVal;
790     int i, iface;
791     char* pTok = NULL;
792     int ip_entry_count = 0;
793     struct ifaddrs *ifaddr, *ifa;
794     int family, s;
795     char host[NI_MAXHOST];
796     struct sockaddr_in6 ipv6_addr;
797     cpu_set_t cpu_set;
798     int c;
799     static char usage[] = "usage: %s -r < use Resource manager: no/yes> -s <outbound sequence number> -f <SA transmit flow Id>\n";
801     ipsecmgr_syslog_init();
804     memset(&globalDB, 0, sizeof(globalDB));
805     globalDB.sa_tx_flow = -1;
806     int temp;
807     while ((c = getopt (argc, argv, "s:f:r:")) != -1)
808     {
809        switch (c)
810        {
811             case 'r':
812                 if(strncmp("yes", optarg,1) == 0)
813                 {
814                     use_rm = 1;
815                 }
816                 break;
818             case 's':
819                 /* check is user input 0 for oseq_offset (valid but also default)*/
820                 if(strncmp("0", optarg,1) == 0)
821                 {
822                     globalDB.oseq_offset = 0;
823                 }
824                 else
825                 {
826                     globalDB.oseq_offset = (uint32_t)strtol(optarg, NULL,0);
827                     if(!globalDB.oseq_offset)
828                     {
829                         printf(usage, argv[0]);
830                         exit(EXIT_FAILURE);
831                     }
832                 }
833                 break;
834             case 'f':
835                 /* check is user input 0 for sa_tx_flow(valid) */
836                 if(strncmp("0", optarg,1) == 0)
837                 {
838                     globalDB.sa_tx_flow= 0;
839                 }
840                 else
841                 {
842                     globalDB.sa_tx_flow = (uint32_t)strtol(optarg, NULL,0);
843                     if(!globalDB.sa_tx_flow)
844                     {
845                         printf(usage, argv[0]);
846                         exit(EXIT_FAILURE);
847                     }
848                 }
849                 break;
850             case '?':
851                 printf(usage, argv[0]);
852                 exit(EXIT_FAILURE);
853             default:
854                 break;
855         }
856     }
857     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
858                    "main: oseq_offset: %d, sa_tx_flow: %d\n",
859                     globalDB.oseq_offset, globalDB.sa_tx_flow);
861     if (use_rm)
862     {
863         if (initRm())
864         {
865             exit(EXIT_FAILURE);
866         }
867     }
869     /* assign main net_test thread to run on core 0 */
870     CPU_ZERO( &cpu_set);
871     CPU_SET( 0, &cpu_set);
872     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
873     /* create netapi */
874     our_netapi_default_cfg.rmHandle = rmClientServiceHandle;
875     netapi_handle = netapi_init(NETAPI_SYS_MASTER,
876                                 &our_netapi_default_cfg);
877     if(netapi_handle == NULL)
878     {
879         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
880                              "ERROR: netapi_init failed\n");
881         return -1;
882     }
883     else
884         netapi_netcpCfgExceptions(netapi_handle,
885                                   NETCP_CFG_ALL_EXCEPTIONS,
886                                   NETCP_CFG_ACTION_DISCARD,
887                                   (NETCP_CFG_ROUTE_HANDLE_T) NULL);
889     if (get_kernel_config())
890     {
891         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
892                             "ERROR: main: get_kernel_config() failed\n");
893         return -1;
894     }
895     else
896     {
897         /* create pktio channel */
898         if(create_pktio_channel())
899         {
900             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
901                             "ERROR: main: pktio channel creation failed\n");
902             return -1;
903         }
904     }
905      /*Create the proxy daemon. */
906     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO, "main: calling daemonize\n");
907     daemonize (LOCK_FILE);
909     /* Initialize and start the IPSec Mgr Snoop functionality */
910     if ((retVal = init_ipsecmgr ()) < 0)
911     {
912         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
913                             "ERROR: IPSec Mgr init failed, error code %d \n",
914                             retVal);
915         return -1;
916     }
917     else
918         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
919                              "main: ipsecmgr daemon shutdonw complete\n");
921     exit(EXIT_SUCCESS);