c04b4f46ac6fc2bc4a74147e7d9e9e463188d121
[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 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
70  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
71 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
72 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
73 #elif defined (DEVICE_K2K)
74 #include <ti/runtime/hplib/device/k2k/src/hplib_device.c>
75 #include <ti/drv/nwal/device/k2k/src/nwal_device.c>
76 #include <ti/runtime/netapi/device/k2k/src/netapi_device.c>
77 #include <ti/drv/qmss/device/k2k/src/qmss_device.c>
78 #include <ti/drv/cppi/device/k2k/src/cppi_device.c>
79 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
80  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
81 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
82 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
83 #elif defined (DEVICE_K2L)
84 #include <ti/runtime/hplib/device/k2l/src/hplib_device.c>
85 #include <ti/drv/nwal/device/k2l/src/nwal_device.c>
86 #include <ti/runtime/netapi/device/k2l/src/netapi_device.c>
87 #include <ti/drv/qmss/device/k2l/src/qmss_device.c>
88 #include <ti/drv/cppi/device/k2l/src/cppi_device.c>
89 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
90  "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/complete-queue"};
91 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
92 "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/flow"};
93 #elif defined (DEVICE_K2E)
94 #include <ti/runtime/hplib/device/k2e/src/hplib_device.c>
95 #include <ti/drv/nwal/device/k2e/src/nwal_device.c>
96 #include <ti/runtime/netapi/device/k2e/src/netapi_device.c>
97 #include <ti/drv/qmss/device/k2e/src/qmss_device.c>
98 #include <ti/drv/cppi/device/k2e/src/cppi_device.c>
99 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
100  "/proc/device-tree/soc/pktdma@24186000/channels/netrx0/complete-queue"};
101 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
102 "/proc/device-tree/soc/pktdma@24186000/channels/netrx0/flow"};
104 #else /*Default */
105 #include <ti/runtime/hplib/device/k2h/src/hplib_device.c>
106 #include <ti/drv/nwal/device/k2h/src/nwal_device.c>
107 #include <ti/runtime/netapi/device/k2h/src/netapi_device.c>
108 #include <ti/drv/qmss/device/k2h/src/qmss_device.c>
109 #include <ti/drv/cppi/device/k2h/src/cppi_device.c>
110 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
111  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
112 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
113 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
115 #endif
117 /**********************************************************************
118  ************************** Local Definitions *************************
119  **********************************************************************/
120 #if 0
122 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
123  "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/complete-queue"};
124 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
125 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow"};
127 char*  DTS_LOG_FILE_QUEUE_ETHx[] = {
128  "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/complete-queue"};
129 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
130 "/proc/device-tree/soc/pktdma@26186000/channels/netrx0/flow"};
131 #endif
134 /**********************************************************************
135  ************************** Global Variables **************************
136  **********************************************************************/
138 static ipsecmgr_ipc_daemon_send_if_t *send_iface;
139 NETAPI_T netapi_handle;
141 ipsecMgrMcb_t globalDB;
143 /* Lock file for the daemon */
144 #define LOCK_FILE   "/var/lock/ipsecmgr_daemon"
146 /* snoop task */
147 static pthread_t    snoop_run_th;
149 static NETAPI_CFG_T our_netapi_default_cfg=
151     TUNE_NETAPI_PERM_MEM_SZ,
152     128,  //start of packet offset for hw to place data on rx for default flow
153     TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
154     TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
155     TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
156     64, //#descriptors w/o buffers in default heap
157     TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
158     128,    //tail room
159     256,    //extra room
160     0
161 };
165 static int QUIT = 0;
167 /* stub functions */
168 static void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
169                          PKTIO_METADATA_T meta[], int n_pkts,
170                          uint64_t ts )
172     return;
175 /* byte swap routine */
176 static unsigned int swap32 (unsigned int x)
178     unsigned int y;
180     y = (((x >> 24) & 0xff) <<  0) |
181         (((x >> 16) & 0xff) <<  8) |
182         (((x >>  8) & 0xff) << 16) |
183         (((x >>  0) & 0xff) << 24) ;
185     return (y);
189 void cleanup_sa_sp()
191     int slot, error=0;;
192     /* delete any offloaded rx SA's and policies */
193     /* and delete any offloaded tx SA's */
194     for (slot = 0;slot < 64;slot++)
195     {
196         if(globalDB.rx_sa[slot].in_use)
197         {
198             globalDB.rx_sa[slot].in_use = 0;
199             if(globalDB.rx_sa[slot].spAppId)
200             {
201                 netapi_secDelRxPolicy(netapi_handle,
202                               (NETCP_CFG_IPSEC_POLICY_T) globalDB.rx_sa[slot].spAppId,
203                               &error);
204                 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
205                 "cleanup_sa_sp: SP deleted: sp_app_id: 0x%x, slot: %d, error: %d\n", 
206                 globalDB.rx_sa[slot].spAppId, slot, error);
207             }
208             netapi_secDelSA(netapi_handle,
209                         NETCP_CFG_NO_INTERFACE,
210                         (NETCP_CFG_SA_T) globalDB.rx_sa[slot].saAppId,
211                         &error);
212             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
213                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
214                 globalDB.rx_sa[slot].saAppId, slot, error);
215             
216         }
217         if(globalDB.tx_sa[slot].in_use)
218         {
219             globalDB.tx_sa[slot].in_use = 0;
220             netapi_secDelSA(netapi_handle,
221                             NETCP_CFG_NO_INTERFACE,
222                            (NETCP_CFG_SA_T) globalDB.tx_sa[slot].saAppId,
223                             &error);
224             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
225                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
226                 globalDB.tx_sa[slot].saAppId, slot, error);
227         }
228     }
232 static void* snoop_run_thread (void* arg)
234     cpu_set_t cpu_set;
235     CPU_ZERO( &cpu_set);
236     CPU_SET( 0, &cpu_set);
238     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
239     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
240         "snoop_run_thread: daemon entering forever event loop\n");
242     while (1)
243     {
244         /* Poll for message from user application */
245         ipsecmgr_ipc_poll();
247         /* Poll for message from Kernel */
248         ipsecmgr_snoop_run();
249         if (QUIT == 1)
250             break;
251     }
252     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
253         "snoop_run_thread: calling shutdown\n");
254     ipsecmgr_snoop_shutdown ();
255     cleanup_sa_sp();
256     netapi_shutdown(netapi_handle);
258     return;
261 /**
262  *  @b Description
263  *  @n  
264  *      SIGTERM handler.
265  *
266  *  @param[in]  signum
267  *      signal number to terminate deamon.
268  */
269 static void sig_term_handler(int signum)
271     QUIT = 1;
274 /**
275  *  @b Description
276  *  @n  
277  *      Function to implement task sleep functionality 
278  *      for IPSecMgr
279  *
280  *  @param[in]  time_in_msec
281  *      Time in milliseconds to sleep
282  *
283  *  @retval
284  *      Not Applicable.
285  */
286 static void task_sleep(uint32_t time_in_msec)
288     pthread_mutex_t fake_mutex = PTHREAD_MUTEX_INITIALIZER;
289     pthread_cond_t fake_cond = PTHREAD_COND_INITIALIZER;
290     struct timespec ts;
291     int rt;
292     unsigned int sec, nsec;
294     sec = time_in_msec/1000;
295     nsec = (time_in_msec - (sec*1000)) * 1000000;
297     /* Use the wall-clock time */
298     clock_gettime(CLOCK_REALTIME, &ts);
300     ts.tv_sec += sec;
301     ts.tv_nsec += nsec;
303     pthread_mutex_lock(&fake_mutex);
304     rt = pthread_cond_timedwait(&fake_cond, &fake_mutex, &ts);
305     pthread_mutex_unlock(&fake_mutex);
309 /**
310  *  @b Description
311  *  @n  
312  *      NETAPI Proxy's IPSecMgr Start Offload Response 
313  *      message handler.
314  *
315  *      This function is called by the IPSecMgr library
316  *      when it has a response ready corresponding to an
317  *      Start Offload SP request issued by the user application.
318  *
319  *  @param[in]  rsp
320  *      IPSecMgr's Start Offload SP response
321  *  @param[in]  addr
322  *      Destination address (user application) to send 
323  *      the response to
324  *  @param[in]  addr_size
325  *      Size of destination address passed
326  *
327  *  @retval
328  *      Success -   0
329  *  @retval
330  *      ERROR   -   <0
331  */
332 static int offload_sp_rsp_send
334     ipsecmgr_snoop_offload_sp_rsp_param_t *rsp,
335     void                                  *addr,
336     uint32_t                              addr_size
339     ipsecmgr_ipc_offload_sp_rsp_param_t offload_sp_rsp;
341     offload_sp_rsp.type = rsp->type;
342     offload_sp_rsp.result = rsp->result;
343     offload_sp_rsp.trans_id = rsp->trans_id;
344     offload_sp_rsp.err_code = rsp->err_code;
345     offload_sp_rsp.sp_handle = rsp->sp_handle;
346     offload_sp_rsp.sa_handle = rsp->sa_handle;
348     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
349         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
350             "offload_sp_rsp_send: addr size not correct\n");
351         return -1;
352     }
354     return send_iface->offload_sp_rsp(&offload_sp_rsp,
355                                       (ipsecmgr_ipc_addr_t *)addr);
357 static void offload_sp_req_recv
359     ipsecmgr_ipc_offload_sp_req_param_t *req,
360     ipsecmgr_ipc_addr_t                 *src_addr
363     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"offload_sp_req_recv called for policy id\n",
364     req->policy_id);
365     ipsecmgr_snoop_offload_sp_rsp_param_t rsp;
366     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
367     ipsecmgr_snoop_offload_sp_req_param_t offload_sp_req;
369     offload_sp_req.trans_id = req->trans_id;
370     offload_sp_req.policy_id = req->policy_id;
371     offload_sp_req.sa_flags = req->sa_flags;
372     offload_sp_req.if_name = req->if_name;
373     offload_sp_req.dscp_cfg = req->dscp_cfg;
374     offload_sp_req.l5_selector = req->l5_selector;
376     memset(&rsp, 0, sizeof(rsp));
377     rsp.trans_id = req->trans_id;
379     if (ipsecmgr_snoop_offload_sp_req(&offload_sp_req, (void*)src_addr,
380                                       addr_size)) {
381         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
382             "offload_sp_req_recv: snoop_offload_sp_req failed\n");
383         rsp.result = RESULT_FAILURE;
384         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
385     }
386     else
387     {
388         rsp.result = RESULT_SUCCESS;
389         rsp.type = RSP_TYPE_ACK;
390     }
391     
392     if (offload_sp_rsp_send(&rsp, (void *)src_addr, addr_size))
393     {
394         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
395             "offload_sp_req_recv: failed to send ACK for offload_sp\n");
396     }
397     return;
401 /**
402  *  @b Description
403  *  @n  
404  *      NETAPI Proxy's IPSecMgr Stop Offload response message 
405  *      handler.
406  *
407  *      This function is called by the IPSecMgr library
408  *      when it has a response ready corresponding to an
409  *      Stop Offload SP request issued by the user application.
410  *
411  *  @param[in]  rsp
412  *      IPSecMgr's Stop Offload SP response
413  *  @param[in]  addr
414  *      Destination address (user application) to send 
415  *      the response to
416  *  @param[in]  addr_size
417  *      Size of destination address passed
418  *
419  *  @retval
420  *      Success -   0
421  *  @retval
422  *      ERROR   -   <0
423  */
424 static int stop_offload_rsp_send
426     ipsecmgr_snoop_stop_offload_rsp_param_t *rsp,
427     void                                    *addr,
428     uint32_t                                addr_size
431     ipsecmgr_ipc_stop_offload_rsp_param_t stop_offload_rsp;
433     stop_offload_rsp.type = rsp->type;
434     stop_offload_rsp.result = rsp->result;
435     stop_offload_rsp.trans_id = rsp->trans_id;
437     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
438         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
439             "stop_offload_rsp_send: addr size not correct\n");
440         return -1;
441     }
443     return send_iface->stop_offload_rsp(&stop_offload_rsp,
444                                       (ipsecmgr_ipc_addr_t *)addr);
447 static void stop_offload_req_recv
449     ipsecmgr_ipc_stop_offload_req_param_t   *req,
450     ipsecmgr_ipc_addr_t                     *src_addr
453     ipsecmgr_snoop_stop_offload_req_param_t stop_offload_req;
454     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
455     ipsecmgr_snoop_stop_offload_rsp_param_t rsp;
457     stop_offload_req.trans_id = req->trans_id;
458     stop_offload_req.policy_id = req->policy_id;
460     memset(&rsp, 0, sizeof(rsp));
461     rsp.trans_id = req->trans_id;
463     if (ipsecmgr_snoop_stop_offload(&stop_offload_req, (void*)src_addr,
464                                       addr_size)) {
465         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
466             "stop_offload_req_recv: snoop_stop_offload failed\n");
467         rsp.result = RESULT_FAILURE;
468         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
469     }
470     else
471     {
472         rsp.result = RESULT_SUCCESS;
473         rsp.type = RSP_TYPE_ACK;
474     }
476     if (stop_offload_rsp_send(&rsp, (void *)src_addr, addr_size))
477     {
478         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
479             "stop_offload_req_recv: failed to send ACK for stop_offload\n");
480     }
481     return;
484 /**
485  *  @b Description
486  *  @n  
487  *      Function to initialize IPSec Manager library.
488  *
489  *  @retval
490  *      Success -   0
491  *  @retval
492  *      ERROR   -   >0
493  */
494 static int32_t init_ipsecmgr (void)
496     struct ipsecmgr_snoop_fp_cfg_cb     fp_cfg_cb;
497     struct ipsecmgr_snoop_mgnt_cb       mgnt_cb;
498     struct ipsecmgr_snoop_platform_cb   plat_cb;
499     ipsecmgr_ipc_daemon_recv_if_t       recv_if;
500     ipsecmgr_ipc_cfg_t                  ipc_cfg;
501     int32_t                             status;
502     pthread_attr_t threadAttr;
504     /* Initializations */
505     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, 
506                         "DEBUG: init_ipsecmgr() starting initialization\n");
507     memset(&fp_cfg_cb, 0, sizeof(fp_cfg_cb));
508     memset(&mgnt_cb, 0, sizeof(mgnt_cb));
509     memset(&plat_cb, 0, sizeof(plat_cb));
510     memset(&recv_if, 0, sizeof(recv_if));
511     memset(&ipc_cfg, 0, sizeof(ipc_cfg));
513     /* Initialize IPC library */
514     ipc_cfg.mode = IPC_MODE_SNOOP_DAEMON;
515     if (ipsecmgr_ipc_init(&ipc_cfg)) {
516         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
517             "init_ipsecmgr: ipc_init failed\n");
518         return -1;
519     }
520     else
521         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
522             "init_ipsecmgr: ipc_init sucess\n");
524     if (ipsecmgr_ipc_get_daemon_send_iface(&send_iface)) {
525         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
526             "init_ipsecmgr: ipc_get_daemon_send_iface failed\n");
527         return -1;
528     }
529     recv_if.offload_sp_req = offload_sp_req_recv;
530     recv_if.stop_offload_req = stop_offload_req_recv;
531     /* Register ipsecmgr daemon recieve i/f */
532     if (ipsecmgr_ipc_register_daemon_recv_iface(&recv_if)) {
533         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
534             "snoop_run: ipc_register_daemon_recv_iface failed\n");
535         return -1;
536     }
538     /* Initialize the IPSec Manager Snoop library */
539     fp_cfg_cb.add_sa        =   netapilib_ifAddSA;
540     fp_cfg_cb.add_sp        =   netapilib_ifAddSP;
541     fp_cfg_cb.del_sa        =   netapilib_ifDeleteSA;
542     fp_cfg_cb.del_sp        =   netapilib_ifDeleteSP;
543     fp_cfg_cb.get_sa_ctx    =   netapilib_ifGetSACtx;
545     plat_cb.log_msg  = (ipsecmgr_snoop_log_msg_t)ipsecmgr_syslog_msg;
546     plat_cb.sleep           =   task_sleep;
548     mgnt_cb.offload_sp_rsp  =   offload_sp_rsp_send;
549     mgnt_cb.stop_offload_rsp=   stop_offload_rsp_send;
550     mgnt_cb.rekey_event     =   NULL; // No explicit notifications needed on Rekey completion
552     if ((status = ipsecmgr_snoop_init (&fp_cfg_cb, &mgnt_cb, &plat_cb))) 
553     {
554         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
555                             "DEBUG: init_ipsecmgr() ipsecmgr_snoop_init failed (%d)\n", status);
556         return -1;
557     }
561 #ifdef GDB_DEBUG
562     snoop_run_thread(NULL);
563 #else
564     /* Create the task context for snoop library */
565     pthread_attr_init(&threadAttr);
566     pthread_attr_setstacksize(&threadAttr, 0x10000);
567     if (pthread_create(&snoop_run_th, (void*) NULL, snoop_run_thread, NULL))
568     {
569         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
570             "ERROR: snoop run thread failed to start, error code\n"); 
571         return -1;
572     }
574     /* Setup signal handler for SIGTERM */
575     if (signal(SIGTERM, sig_term_handler) == SIG_ERR) {
576         ipsecmgr_syslog_msg(SYSLOG_LEVEL_WARN,
577             "init_ipsecmgr: cannot handle SIGTERM\n");
578     }
579     /* Wait for the NETAPI Proxy task to finish its processing and exit. */
580     pthread_join (snoop_run_th, NULL);
581 #endif
582     return 0;
585 /**
586  *  @b Description
587  *  @n  
588  *      Utility function to daemonize the current
589  *      application.
590  *
591  *  @param[in]  lock_file
592  *      Lock file to be used by the daemon
593  */
594 static void daemonize (const char *lock_file)
596     pid_t       pid, sid;
597     int32_t     lock_fp = -1;
598     char        str[10];
600     /* already a daemon */
601     if (getppid () == 1)
602         return;
604     /* Fork off the parent process */
605     if ((pid = fork ()) < 0) 
606     {
607         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
608                             "ERROR: daemonize() unable to fork daemon, code=%d (%s)",
609                             errno, 
610                             strerror(errno));
611         exit (-1);
612     }
614     /* If we got a PID, then exit the parent process. */
615     if (pid > 0)
616         exit (0);
618     /* At this point we are executing as the child process */
620     /* Create a new SID for the child process */
621     if ((sid = setsid ()) < 0) 
622     {
623         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
624                             "ERROR: daemonize() unable to create a new session, code %d (%s)",
625                             errno, 
626                             strerror(errno));
627         exit (-1);
628     }
630     /* Change the file mode mask */
631     umask (027);
633     /* Change the current working directory.  This prevents the current
634      * directory from being locked; hence not being able to remove it. */
635     if ((chdir("/")) < 0) 
636     {
637         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
638                             "ERROR: daemonize() unable to change directory to %s, code %d (%s)",
639                             "/", 
640                             errno, 
641                             strerror(errno));
642         exit (-1);
643     }
645     /* Create the lock file */
646     if (lock_file) 
647     {
648         if ((lock_fp = open(lock_file, O_RDWR|O_CREAT, 0640)) < 0 ) 
649         {
650             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
651                                 "ERROR: daemonize() unable to create lock file %s, code=%d (%s)",
652                                 lock_file, 
653                                 errno, 
654                                 strerror(errno));
655             exit (-1);
656         }
657     }
659     if (lockf (lock_fp, F_TLOCK, 0) < 0) 
660         exit(-1); /* can not lock */
662     /* Record pid to lockfile */
663     sprintf (str, "%d\n", getpid());
664     write (lock_fp, str, strlen(str)); 
666     /* Cancel certain signals */
667     signal (SIGCHLD, SIG_DFL); /* A child process dies */
668     signal (SIGTSTP, SIG_IGN); /* Various TTY signals */
669     signal (SIGTTOU, SIG_IGN);
670     signal (SIGTTIN, SIG_IGN);
671     signal (SIGHUP, SIG_IGN); /* Ignore hangup signal */
672     signal (SIGTERM, sig_term_handler); /* catch SIGTERM */
674     /* Redirect standard files to /dev/null */
675     freopen( "/dev/null", "r", stdin);
676     freopen( "/dev/null", "w", stdout);
677     freopen( "/dev/null", "w", stderr);
679     /* Done setting up the daemon */
680     return;
683 int get_kernel_config()
685     uint32_t temp=0;
686     FILE *pDts = NULL;
688     pDts = fopen(DTS_LOG_FILE_QUEUE_ETHx[0], "rb");
690     if(pDts)
691     {
692         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
693         globalDB.qNum = (int)swap32(temp);
694         fclose(pDts);
695     }
696     else
697     {
698         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
699             "main: error opening device tree file: %s\n",DTS_LOG_FILE_QUEUE_ETHx[0]);
700         return -1;
701     }
703     pDts = NULL;
704     pDts = fopen(DTS_LOG_FILE_FLOW_ETHx[0], "rb");
706     if(pDts)
707     {
708         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
709         globalDB.flowId = (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_FLOW_ETHx[0]);
716         return -1;
717     }
718     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
719             "get_kernel_config: flow: 0x%x, qNum: 0x%x\n", 
720              globalDB.flowId, globalDB.qNum);
721     return 0;
724 int create_pktio_channel()
726     static int count = 0;
727     int error = 0;
728     char name[19];
729     PKTIO_HANDLE_T *pktio_channel;
730     PKTIO_CFG_T pktio_cfg;
731     NETCP_CFG_ROUTE_T route;
732     NETCP_CFG_FLOW_T flow;
733     NETCP_CFG_EXCEPTION_PKT_T expPkt_appid = 0;
735     memset(&pktio_cfg,0,sizeof(PKTIO_CFG_T));
736     memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
737     memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
739     sprintf(&name[0],"%s","offload_0");
740     pktio_cfg.qnum = globalDB.qNum;
741     pktio_cfg.flags1 = PKTIO_RX;
742     pktio_cfg.flags2 = PKTIO_GLOBAL | PKTIO_PKT;
743     pktio_cfg.max_n = 8;
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     ipsecmgr_syslog_init();
800     memset(&globalDB, 0, sizeof(globalDB));
802     /* assign main net_test thread to run on core 0 */
803     CPU_ZERO( &cpu_set);
804     CPU_SET( 0, &cpu_set);
805     hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
806     /* create netapi */
807     netapi_handle = netapi_init(NETAPI_SYS_MASTER,
808                                 &our_netapi_default_cfg,
809                                 &hplibDeviceGblCfgParam,
810                                 &nwalDeviceGblCfgParam,
811                                 &netapiDeviceGblCfgParam);
812     if(netapi_handle == NULL)
813     {
814         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
815                              "ERROR: netapi_init failed\n");
816         return -1;
817     }
818     else
819         netapi_netcpCfgExceptions(netapi_handle,
820                                   NETCP_CFG_ALL_EXCEPTIONS,
821                                   NETCP_CFG_ACTION_DISCARD,
822                                   (NETCP_CFG_ROUTE_HANDLE_T) NULL);
824     if (get_kernel_config())
825     {
826         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
827                             "ERROR: main: get_kernel_config() failed\n");
828         return -1;
829     }
830     else
831     {
832         /* create pktio channel */
833         if(create_pktio_channel())
834         {
835             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
836                             "ERROR: main: pktio channel creation failed\n");
837             return -1;
838         }
839     }
840      /*Create the proxy daemon. */
841     printf("main: calling daemonize\n");
842     daemonize (LOCK_FILE); 
844     /* Initialize and start the IPSec Mgr Snoop functionality */
845     if ((retVal = init_ipsecmgr ()) < 0)
846     {
847         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
848                             "ERROR: IPSec Mgr init failed, error code %d \n",
849                             retVal);
850         return -1;
851     }
852     else
853         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
854                              "main: ipsecmgr daemon shutdonw complete\n");