eaf7f60904c71f34da3b844f00732c1cc097d576
[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/runtime/hplib/device/k2h/src/hplib_device.c>
65 #include <ti/drv/nwal/device/k2h/src/nwal_device.c>
66 #include <ti/runtime/netapi/device/k2h/src/netapi_device.c>
67 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
68 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
69 #elif defined (DEVICE_K2K)
70 #include <ti/runtime/hplib/device/k2k/src/hplib_device.c>
71 #include <ti/drv/nwal/device/k2k/src/nwal_device.c>
72 #include <ti/runtime/netapi/device/k2k/src/netapi_device.c>
73 #include <ti/drv/qmss/device/k2k/src/qmss_device.c>
74 #include <ti/drv/cppi/device/k2k/src/cppi_device.c>
75 #elif defined (DEVICE_K2L)
76 #include <ti/runtime/hplib/device/k2l/src/hplib_device.c>
77 #include <ti/drv/nwal/device/k2l/src/nwal_device.c>
78 #include <ti/runtime/netapi/device/k2l/src/netapi_device.c>
79 #include <ti/drv/qmss/device/k2l/src/qmss_device.c>
80 #include <ti/drv/cppi/device/k2l/src/cppi_device.c>
81 #elif defined (DEVICE_K2E)
82 #include <ti/runtime/hplib/device/k2e/src/hplib_device.c>
83 #include <ti/drv/nwal/device/k2e/src/nwal_device.c>
84 #include <ti/runtime/netapi/device/k2e/src/netapi_device.c>
85 #include <ti/drv/qmss/device/k2e/src/qmss_device.c>
86 #include <ti/drv/cppi/device/k2e/src/cppi_device.c>
87 #else /*Default */
88 #include <ti/runtime/hplib/device/k2h/src/hplib_device.c>
89 #include <ti/drv/nwal/device/k2h/src/nwal_device.c>
90 #include <ti/runtime/netapi/device/k2h/src/netapi_device.c>
91 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
92 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
93 #endif
95 /**********************************************************************
96  ************************** Local Definitions *************************
97  **********************************************************************/
98 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
99  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
100 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
101 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
104 /**********************************************************************
105  ************************** Global Variables **************************
106  **********************************************************************/
108 static ipsecmgr_ipc_daemon_send_if_t *send_iface;
109 NETAPI_T netapi_handle;
111 ipsecMgrMcb_t globalDB;
113 /* Lock file for the daemon */
114 #define LOCK_FILE   "/var/lock/ipsecmgr_daemon"
116 /* snoop task */
117 static pthread_t    snoop_run_th;
119 static NETAPI_CFG_T our_netapi_default_cfg=
121     TUNE_NETAPI_PERM_MEM_SZ,
122     128,  //start of packet offset for hw to place data on rx for default flow
123     TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
124     TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
125     TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
126     64, //#descriptors w/o buffers in default heap
127     TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
128     128,    //tail room
129     256,    //extra room
130     0
131 };
135 static int QUIT = 0;
137 /* stub functions */
138 static void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
139                          PKTIO_METADATA_T meta[], int n_pkts,
140                          uint64_t ts )
142     return;
145 /* byte swap routine */
146 static unsigned int swap32 (unsigned int x)
148     unsigned int y;
150     y = (((x >> 24) & 0xff) <<  0) |
151         (((x >> 16) & 0xff) <<  8) |
152         (((x >>  8) & 0xff) << 16) |
153         (((x >>  0) & 0xff) << 24) ;
155     return (y);
159 void cleanup_sa_sp()
161     int slot, error=0;;
162     /* delete any offloaded rx SA's and policies */
163     /* and delete any offloaded tx SA's */
164     for (slot = 0;slot < 64;slot++)
165     {
166         if(globalDB.rx_sa[slot].in_use)
167         {
168             globalDB.rx_sa[slot].in_use = 0;
169             if(globalDB.rx_sa[slot].spAppId)
170             {
171                 netapi_secDelRxPolicy(netapi_handle,
172                               (NETCP_CFG_IPSEC_POLICY_T) globalDB.rx_sa[slot].spAppId,
173                               &error);
174                 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
175                 "cleanup_sa_sp: SP deleted: sp_app_id: 0x%x, slot: %d, error: %d\n", 
176                 globalDB.rx_sa[slot].spAppId, slot, error);
177             }
178             netapi_secDelSA(netapi_handle,
179                         NETCP_CFG_NO_INTERFACE,
180                         (NETCP_CFG_SA_T) globalDB.rx_sa[slot].saAppId,
181                         &error);
182             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
183                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
184                 globalDB.rx_sa[slot].saAppId, slot, error);
185             
186         }
187         if(globalDB.tx_sa[slot].in_use)
188         {
189             globalDB.tx_sa[slot].in_use = 0;
190             netapi_secDelSA(netapi_handle,
191                             NETCP_CFG_NO_INTERFACE,
192                            (NETCP_CFG_SA_T) globalDB.tx_sa[slot].saAppId,
193                             &error);
194             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
195                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
196                 globalDB.tx_sa[slot].saAppId, slot, error);
197         }
198     }
202 static void* snoop_run_thread (void* arg)
204     cpu_set_t cpu_set;
205     CPU_ZERO( &cpu_set);
206     CPU_SET( 0, &cpu_set);
208     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
209     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
210         "snoop_run_thread: daemon entering forever event loop\n");
212     while (1)
213     {
214         /* Poll for message from user application */
215         ipsecmgr_ipc_poll();
217         /* Poll for message from Kernel */
218         ipsecmgr_snoop_run();
219         if (QUIT == 1)
220             break;
221     }
222     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
223         "snoop_run_thread: calling shutdown\n");
224     ipsecmgr_snoop_shutdown ();
225     cleanup_sa_sp();
226     netapi_shutdown(netapi_handle);
228     return;
231 /**
232  *  @b Description
233  *  @n  
234  *      SIGTERM handler.
235  *
236  *  @param[in]  signum
237  *      signal number to terminate deamon.
238  */
239 static void sig_term_handler(int signum)
241     QUIT = 1;
244 /**
245  *  @b Description
246  *  @n  
247  *      Function to implement task sleep functionality 
248  *      for IPSecMgr
249  *
250  *  @param[in]  time_in_msec
251  *      Time in milliseconds to sleep
252  *
253  *  @retval
254  *      Not Applicable.
255  */
256 static void task_sleep(uint32_t time_in_msec)
258     pthread_mutex_t fake_mutex = PTHREAD_MUTEX_INITIALIZER;
259     pthread_cond_t fake_cond = PTHREAD_COND_INITIALIZER;
260     struct timespec ts;
261     int rt;
262     unsigned int sec, nsec;
264     sec = time_in_msec/1000;
265     nsec = (time_in_msec - (sec*1000)) * 1000000;
267     /* Use the wall-clock time */
268     clock_gettime(CLOCK_REALTIME, &ts);
270     ts.tv_sec += sec;
271     ts.tv_nsec += nsec;
273     pthread_mutex_lock(&fake_mutex);
274     rt = pthread_cond_timedwait(&fake_cond, &fake_mutex, &ts);
275     pthread_mutex_unlock(&fake_mutex);
279 /**
280  *  @b Description
281  *  @n  
282  *      NETAPI Proxy's IPSecMgr Start Offload Response 
283  *      message handler.
284  *
285  *      This function is called by the IPSecMgr library
286  *      when it has a response ready corresponding to an
287  *      Start Offload SP request issued by the user application.
288  *
289  *  @param[in]  rsp
290  *      IPSecMgr's Start Offload SP response
291  *  @param[in]  addr
292  *      Destination address (user application) to send 
293  *      the response to
294  *  @param[in]  addr_size
295  *      Size of destination address passed
296  *
297  *  @retval
298  *      Success -   0
299  *  @retval
300  *      ERROR   -   <0
301  */
302 static int offload_sp_rsp_send
304     ipsecmgr_snoop_offload_sp_rsp_param_t *rsp,
305     void                                  *addr,
306     uint32_t                              addr_size
309     ipsecmgr_ipc_offload_sp_rsp_param_t offload_sp_rsp;
311     offload_sp_rsp.type = rsp->type;
312     offload_sp_rsp.result = rsp->result;
313     offload_sp_rsp.trans_id = rsp->trans_id;
314     offload_sp_rsp.err_code = rsp->err_code;
315     offload_sp_rsp.sp_handle = rsp->sp_handle;
316     offload_sp_rsp.sa_handle = rsp->sa_handle;
318     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
319         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
320             "offload_sp_rsp_send: addr size not correct\n");
321         return -1;
322     }
324     return send_iface->offload_sp_rsp(&offload_sp_rsp,
325                                       (ipsecmgr_ipc_addr_t *)addr);
327 static void offload_sp_req_recv
329     ipsecmgr_ipc_offload_sp_req_param_t *req,
330     ipsecmgr_ipc_addr_t                 *src_addr
333     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"offload_sp_req_recv called for policy id\n",
334     req->policy_id);
335     ipsecmgr_snoop_offload_sp_rsp_param_t rsp;
336     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
337     ipsecmgr_snoop_offload_sp_req_param_t offload_sp_req;
339     offload_sp_req.trans_id = req->trans_id;
340     offload_sp_req.policy_id = req->policy_id;
341     offload_sp_req.sa_flags = req->sa_flags;
342     offload_sp_req.if_name = req->if_name;
343     offload_sp_req.dscp_cfg = req->dscp_cfg;
344     offload_sp_req.l5_selector = req->l5_selector;
346     memset(&rsp, 0, sizeof(rsp));
347     rsp.trans_id = req->trans_id;
349     if (ipsecmgr_snoop_offload_sp_req(&offload_sp_req, (void*)src_addr,
350                                       addr_size)) {
351         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
352             "offload_sp_req_recv: snoop_offload_sp_req failed\n");
353         rsp.result = RESULT_FAILURE;
354         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
355     }
356     else
357     {
358         rsp.result = RESULT_SUCCESS;
359         rsp.type = RSP_TYPE_ACK;
360     }
361     
362     if (offload_sp_rsp_send(&rsp, (void *)src_addr, addr_size))
363     {
364         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
365             "offload_sp_req_recv: failed to send ACK for offload_sp\n");
366     }
367     return;
371 /**
372  *  @b Description
373  *  @n  
374  *      NETAPI Proxy's IPSecMgr Stop Offload response message 
375  *      handler.
376  *
377  *      This function is called by the IPSecMgr library
378  *      when it has a response ready corresponding to an
379  *      Stop Offload SP request issued by the user application.
380  *
381  *  @param[in]  rsp
382  *      IPSecMgr's Stop Offload SP response
383  *  @param[in]  addr
384  *      Destination address (user application) to send 
385  *      the response to
386  *  @param[in]  addr_size
387  *      Size of destination address passed
388  *
389  *  @retval
390  *      Success -   0
391  *  @retval
392  *      ERROR   -   <0
393  */
394 static int stop_offload_rsp_send
396     ipsecmgr_snoop_stop_offload_rsp_param_t *rsp,
397     void                                    *addr,
398     uint32_t                                addr_size
401     ipsecmgr_ipc_stop_offload_rsp_param_t stop_offload_rsp;
403     stop_offload_rsp.type = rsp->type;
404     stop_offload_rsp.result = rsp->result;
405     stop_offload_rsp.trans_id = rsp->trans_id;
407     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
408         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
409             "stop_offload_rsp_send: addr size not correct\n");
410         return -1;
411     }
413     return send_iface->stop_offload_rsp(&stop_offload_rsp,
414                                       (ipsecmgr_ipc_addr_t *)addr);
417 static void stop_offload_req_recv
419     ipsecmgr_ipc_stop_offload_req_param_t   *req,
420     ipsecmgr_ipc_addr_t                     *src_addr
423     ipsecmgr_snoop_stop_offload_req_param_t stop_offload_req;
424     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
425     ipsecmgr_snoop_stop_offload_rsp_param_t rsp;
427     stop_offload_req.trans_id = req->trans_id;
428     stop_offload_req.policy_id = req->policy_id;
430     memset(&rsp, 0, sizeof(rsp));
431     rsp.trans_id = req->trans_id;
433     if (ipsecmgr_snoop_stop_offload(&stop_offload_req, (void*)src_addr,
434                                       addr_size)) {
435         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
436             "stop_offload_req_recv: snoop_stop_offload failed\n");
437         rsp.result = RESULT_FAILURE;
438         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
439     }
440     else
441     {
442         rsp.result = RESULT_SUCCESS;
443         rsp.type = RSP_TYPE_ACK;
444     }
446     if (stop_offload_rsp_send(&rsp, (void *)src_addr, addr_size))
447     {
448         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
449             "stop_offload_req_recv: failed to send ACK for stop_offload\n");
450     }
451     return;
454 /**
455  *  @b Description
456  *  @n  
457  *      Function to initialize IPSec Manager library.
458  *
459  *  @retval
460  *      Success -   0
461  *  @retval
462  *      ERROR   -   >0
463  */
464 static int32_t init_ipsecmgr (void)
466     struct ipsecmgr_snoop_fp_cfg_cb     fp_cfg_cb;
467     struct ipsecmgr_snoop_mgnt_cb       mgnt_cb;
468     struct ipsecmgr_snoop_platform_cb   plat_cb;
469     ipsecmgr_ipc_daemon_recv_if_t       recv_if;
470     ipsecmgr_ipc_cfg_t                  ipc_cfg;
471     int32_t                             status;
472     pthread_attr_t threadAttr;
474     /* Initializations */
475     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, 
476                         "DEBUG: init_ipsecmgr() starting initialization\n");
477     memset(&fp_cfg_cb, 0, sizeof(fp_cfg_cb));
478     memset(&mgnt_cb, 0, sizeof(mgnt_cb));
479     memset(&plat_cb, 0, sizeof(plat_cb));
480     memset(&recv_if, 0, sizeof(recv_if));
481     memset(&ipc_cfg, 0, sizeof(ipc_cfg));
483     /* Initialize IPC library */
484     ipc_cfg.mode = IPC_MODE_SNOOP_DAEMON;
485     if (ipsecmgr_ipc_init(&ipc_cfg)) {
486         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
487             "init_ipsecmgr: ipc_init failed\n");
488         return -1;
489     }
490     else
491         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
492             "init_ipsecmgr: ipc_init sucess\n");
494     if (ipsecmgr_ipc_get_daemon_send_iface(&send_iface)) {
495         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
496             "init_ipsecmgr: ipc_get_daemon_send_iface failed\n");
497         return -1;
498     }
499     recv_if.offload_sp_req = offload_sp_req_recv;
500     recv_if.stop_offload_req = stop_offload_req_recv;
501     /* Register ipsecmgr daemon recieve i/f */
502     if (ipsecmgr_ipc_register_daemon_recv_iface(&recv_if)) {
503         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
504             "snoop_run: ipc_register_daemon_recv_iface failed\n");
505         return -1;
506     }
508     /* Initialize the IPSec Manager Snoop library */
509     fp_cfg_cb.add_sa        =   netapilib_ifAddSA;
510     fp_cfg_cb.add_sp        =   netapilib_ifAddSP;
511     fp_cfg_cb.del_sa        =   netapilib_ifDeleteSA;
512     fp_cfg_cb.del_sp        =   netapilib_ifDeleteSP;
513     fp_cfg_cb.get_sa_ctx    =   netapilib_ifGetSACtx;
515     plat_cb.log_msg  = (ipsecmgr_snoop_log_msg_t)ipsecmgr_syslog_msg;
516     plat_cb.sleep           =   task_sleep;
518     mgnt_cb.offload_sp_rsp  =   offload_sp_rsp_send;
519     mgnt_cb.stop_offload_rsp=   stop_offload_rsp_send;
520     mgnt_cb.rekey_event     =   NULL; // No explicit notifications needed on Rekey completion
522     if ((status = ipsecmgr_snoop_init (&fp_cfg_cb, &mgnt_cb, &plat_cb))) 
523     {
524         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
525                             "DEBUG: init_ipsecmgr() ipsecmgr_snoop_init failed (%d)\n", status);
526         return -1;
527     }
531 #ifdef GDB_DEBUG
532     snoop_run_thread(NULL);
533 #else
534     /* Create the task context for snoop library */
535     pthread_attr_init(&threadAttr);
536     pthread_attr_setstacksize(&threadAttr, 0x10000);
537     if (pthread_create(&snoop_run_th, (void*) NULL, snoop_run_thread, NULL))
538     {
539         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
540             "ERROR: snoop run thread failed to start, error code\n"); 
541         return -1;
542     }
544     /* Setup signal handler for SIGTERM */
545     if (signal(SIGTERM, sig_term_handler) == SIG_ERR) {
546         ipsecmgr_syslog_msg(SYSLOG_LEVEL_WARN,
547             "init_ipsecmgr: cannot handle SIGTERM\n");
548     }
549     /* Wait for the NETAPI Proxy task to finish its processing and exit. */
550     pthread_join (snoop_run_th, NULL);
551 #endif
552     return 0;
555 /**
556  *  @b Description
557  *  @n  
558  *      Utility function to daemonize the current
559  *      application.
560  *
561  *  @param[in]  lock_file
562  *      Lock file to be used by the daemon
563  */
564 static void daemonize (const char *lock_file)
566     pid_t       pid, sid;
567     int32_t     lock_fp = -1;
568     char        str[10];
570     /* already a daemon */
571     if (getppid () == 1)
572         return;
574     /* Fork off the parent process */
575     if ((pid = fork ()) < 0) 
576     {
577         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
578                             "ERROR: daemonize() unable to fork daemon, code=%d (%s)",
579                             errno, 
580                             strerror(errno));
581         exit (-1);
582     }
584     /* If we got a PID, then exit the parent process. */
585     if (pid > 0)
586         exit (0);
588     /* At this point we are executing as the child process */
590     /* Create a new SID for the child process */
591     if ((sid = setsid ()) < 0) 
592     {
593         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
594                             "ERROR: daemonize() unable to create a new session, code %d (%s)",
595                             errno, 
596                             strerror(errno));
597         exit (-1);
598     }
600     /* Change the file mode mask */
601     umask (027);
603     /* Change the current working directory.  This prevents the current
604      * directory from being locked; hence not being able to remove it. */
605     if ((chdir("/")) < 0) 
606     {
607         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
608                             "ERROR: daemonize() unable to change directory to %s, code %d (%s)",
609                             "/", 
610                             errno, 
611                             strerror(errno));
612         exit (-1);
613     }
615     /* Create the lock file */
616     if (lock_file) 
617     {
618         if ((lock_fp = open(lock_file, O_RDWR|O_CREAT, 0640)) < 0 ) 
619         {
620             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
621                                 "ERROR: daemonize() unable to create lock file %s, code=%d (%s)",
622                                 lock_file, 
623                                 errno, 
624                                 strerror(errno));
625             exit (-1);
626         }
627     }
629     if (lockf (lock_fp, F_TLOCK, 0) < 0) 
630         exit(-1); /* can not lock */
632     /* Record pid to lockfile */
633     sprintf (str, "%d\n", getpid());
634     write (lock_fp, str, strlen(str)); 
636     /* Cancel certain signals */
637     signal (SIGCHLD, SIG_DFL); /* A child process dies */
638     signal (SIGTSTP, SIG_IGN); /* Various TTY signals */
639     signal (SIGTTOU, SIG_IGN);
640     signal (SIGTTIN, SIG_IGN);
641     signal (SIGHUP, SIG_IGN); /* Ignore hangup signal */
642     signal (SIGTERM, sig_term_handler); /* catch SIGTERM */
644     /* Redirect standard files to /dev/null */
645     freopen( "/dev/null", "r", stdin);
646     freopen( "/dev/null", "w", stdout);
647     freopen( "/dev/null", "w", stderr);
649     /* Done setting up the daemon */
650     return;
653 int get_kernel_config()
655     uint32_t temp=0;
656     FILE *pDts = NULL;
658     pDts = fopen(DTS_LOG_FILE_QUEUE_ETHx[0], "rb");
660     if(pDts)
661     {
662         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
663         globalDB.qNum = (int)swap32(temp);
664         fclose(pDts);
665     }
666     else
667     {
668         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
669             "main: error opening device tree file: %s\n",DTS_LOG_FILE_QUEUE_ETHx[0]);
670         return -1;
671     }
673     pDts = NULL;
674     pDts = fopen(DTS_LOG_FILE_FLOW_ETHx[0], "rb");
676     if(pDts)
677     {
678         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
679         globalDB.flowId = (int)swap32(temp);
680         fclose(pDts);
681     }
682     else
683     {
684         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
685             "main: error opening device tree file: %s\n",DTS_LOG_FILE_FLOW_ETHx[0]);
686         return -1;
687     }
688     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
689             "get_kernel_config: flow: 0x%x, qNum: 0x%x\n", 
690              globalDB.flowId, globalDB.qNum);
691     return 0;
694 int create_pktio_channel()
696     static int count = 0;
697     int error = 0;
698     char name[19];
699     PKTIO_HANDLE_T *pktio_channel;
700     PKTIO_CFG_T pktio_cfg;
701     NETCP_CFG_ROUTE_T route;
702     NETCP_CFG_FLOW_T flow;
703     NETCP_CFG_EXCEPTION_PKT_T expPkt_appid = 0;
705     memset(&pktio_cfg,0,sizeof(PKTIO_CFG_T));
706     memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
707     memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
709     sprintf(&name[0],"%s","offload_0");
710     pktio_cfg.qnum = globalDB.qNum;
711     pktio_cfg.flags1 = PKTIO_RX;
712     pktio_cfg.flags2 = PKTIO_GLOBAL | PKTIO_PKT;
713     pktio_cfg.max_n = 8;
715     globalDB.pktio_channel = netapi_pktioCreate(netapi_handle,
716                                                &name[0],
717                                                (PKTIO_CB)recv_cb,
718                                                &pktio_cfg,
719                                                &error);
720     if (!globalDB.pktio_channel)
721     {
722         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
723             "create_pktio_channel: failed\n");
724         return -1;
725     }
727     printf("create_pktio_channel: qnum: %d, pktio_handle: 0x%x\n",
728             pktio_cfg.qnum,
729             globalDB.pktio_channel);
731     flow.dma_engine= 1;
732     flow.flowid = globalDB.flowId;
733     route.p_dest_q = globalDB.pktio_channel;
734     route.p_flow = &flow;
735     route.valid_params |= NETCP_CFG_VALID_PARAM_ROUTE_TYPE;
736     route.routeType = NWAL_ROUTE_RX_INTF_W_FLOW;
737     /* enable exception packet handling for fragmented packets */
738     expPkt_appid = netapi_netcpCfgExceptions(netapi_handle,
739                                              7,
740                                              NETCP_CFG_ACTION_TO_SW,
741                                              (NETCP_CFG_ROUTE_HANDLE_T) &route);
742     printf("create_pktio_channel: expPkt appid: 0x%x\n", expPkt_appid);
744     return 0;
746 /**
747  *  @b Description
748  *  @n  
749  *      Entry point for the NETAPI Proxy application.
750  *
751  *  @param[in]  argc
752  *      Number of arguments passed to the application
753  *  @param[in]  argv
754  *      Arguments passed to the application.
755  *
756  *  @retval
757  *      Success -   0
758  *  @retval
759  *      ERROR   -   >0
760  */
761 int32_t main (int argc, char* argv[])
763     int32_t             retVal;
764     int i, iface;
765     char* pTok = NULL;
766     int ip_entry_count = 0;
767     struct ifaddrs *ifaddr, *ifa;
768     int family, s;
769     char host[NI_MAXHOST];
770     struct sockaddr_in6 ipv6_addr;
771     cpu_set_t cpu_set;
772     ipsecmgr_syslog_init();
774     memset(&globalDB, 0, sizeof(globalDB));
776     /* assign main net_test thread to run on core 0 */
777     CPU_ZERO( &cpu_set);
778     CPU_SET( 0, &cpu_set);
779     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
780     /* create netapi */
781     netapi_handle = netapi_init(NETAPI_SYS_MASTER,
782                                 &our_netapi_default_cfg,
783                                 &hplibDeviceGblCfgParam,
784                                 &nwalDeviceGblCfgParam,
785                                 &netapiDeviceGblCfgParam);
786     if(netapi_handle == NULL)
787     {
788         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
789                              "ERROR: netapi_init failed\n");
790         return -1;
791     }
792     else
793         netapi_netcpCfgExceptions(netapi_handle,
794                                   NETCP_CFG_ALL_EXCEPTIONS,
795                                   NETCP_CFG_ACTION_DISCARD,
796                                   (NETCP_CFG_ROUTE_HANDLE_T) NULL);
798     if (get_kernel_config())
799     {
800         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
801                             "ERROR: main: get_kernel_config() failed\n");
802         return -1;
803     }
804     else
805     {
806         /* create pktio channel */
807         if(create_pktio_channel())
808         {
809             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
810                             "ERROR: main: pktio channel creation failed\n");
811             return -1;
812         }
813     }
814      /*Create the proxy daemon. */
815     printf("main: calling daemonize\n");
816     daemonize (LOCK_FILE); 
818     /* Initialize and start the IPSec Mgr Snoop functionality */
819     if ((retVal = init_ipsecmgr ()) < 0)
820     {
821         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
822                             "ERROR: IPSec Mgr init failed, error code %d \n",
823                             retVal);
824         return -1;
825     }
826     else
827         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
828                              "main: ipsecmgr daemon shutdonw complete\n");