Support for multiple interfaces
[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  "/proc/device-tree/soc/pktdma@2004000/channels/netrx1/complete-queue",
69  "/proc/device-tree/soc/pktdma@2004000/channels/netrx2/complete-queue",
70  "/proc/device-tree/soc/pktdma@2004000/channels/netrx3/complete-queue",
71  "/proc/device-tree/soc/pktdma@2004000/channels/netrx4/complete-queue",
72  "/proc/device-tree/soc/pktdma@2004000/channels/netrx5/complete-queue",
73  "/proc/device-tree/soc/pktdma@2004000/channels/netrx6/complete-queue",
74  "/proc/device-tree/soc/pktdma@2004000/channels/netrx7/complete-queue",
75  "/proc/device-tree/soc/pktdma@2004000/channels/netrx8/complete-queue",
76  "/proc/device-tree/soc/pktdma@2004000/channels/netrx9/complete-queue",
77  "/proc/device-tree/soc/pktdma@2004000/channels/netrx10/complete-queue",
78  "/proc/device-tree/soc/pktdma@2004000/channels/netrx11/complete-queue",
79  "/proc/device-tree/soc/pktdma@2004000/channels/netrx12/complete-queue",
80  "/proc/device-tree/soc/pktdma@2004000/channels/netrx13/complete-queue",
81  "/proc/device-tree/soc/pktdma@2004000/channels/netrx14/complete-queue",
82  "/proc/device-tree/soc/pktdma@2004000/channels/netrx15/complete-queue"
83 };
84 char*  DTS_LOG_FILE_FLOW_ETHx[] = {
85 "/proc/device-tree/soc/pktdma@2004000/channels/netrx0/flow",
86 "/proc/device-tree/soc/pktdma@2004000/channels/netrx1/flow",
87 "/proc/device-tree/soc/pktdma@2004000/channels/netrx2/flow",
88 "/proc/device-tree/soc/pktdma@2004000/channels/netrx3/flow",
89 "/proc/device-tree/soc/pktdma@2004000/channels/netrx4/flow",
90 "/proc/device-tree/soc/pktdma@2004000/channels/netrx5/flow",
91 "/proc/device-tree/soc/pktdma@2004000/channels/netrx6/flow",
92 "/proc/device-tree/soc/pktdma@2004000/channels/netrx7/flow",
93 "/proc/device-tree/soc/pktdma@2004000/channels/netrx8/flow",
94 "/proc/device-tree/soc/pktdma@2004000/channels/netrx9/flow",
95 "/proc/device-tree/soc/pktdma@2004000/channels/netrx10/flow",
96 "/proc/device-tree/soc/pktdma@2004000/channels/netrx11/flow",
97 "/proc/device-tree/soc/pktdma@2004000/channels/netrx12/flow",
98 "/proc/device-tree/soc/pktdma@2004000/channels/netrx13/flow",
99 "/proc/device-tree/soc/pktdma@2004000/channels/netrx14/flow",
100 "/proc/device-tree/soc/pktdma@2004000/channels/netrx15/flow",
101 };
103 /**********************************************************************
104  ************************** Global Variables **************************
105  **********************************************************************/
107 static ipsecmgr_ipc_daemon_send_if_t *send_iface;
108 NETAPI_T netapi_handle;
110 //paSysStats_t netcp_stats;
111 ipsecMgrMcb_t globalDB;
112 ipsecMgrIfConfigEntry_T ipConfigList[16];
114 /* Lock file for the daemon */
115 #define LOCK_FILE   "/var/lock/ipsecmgr_daemon"
117 /* snoop task */
118 static pthread_t    snoop_run_th;
120 static NETAPI_CFG_T our_netapi_default_cfg=
122     TUNE_NETAPI_PERM_MEM_SZ,
123     128,  //start of packet offset for hw to place data on rx for default flow
124     TUNE_NETAPI_QM_CONFIG_MAX_DESC_NUM, //max number of descriptors in system
125     TUNE_NETAPI_NUM_GLOBAL_DESC,        //total we will use
126     TUNE_NETAPI_DEFAULT_NUM_BUFFERS,   //#descriptors+buffers in default heap
127     64, //#descriptors w/o buffers in default heap
128     TUNE_NETAPI_DEFAULT_BUFFER_SIZE+128+128,  //size of buffers in default heap
129     128   ,  //tail room
130     256      //extra room
131 };
136 static int QUIT = 0;
138 /* stub functions */
139 static void recv_cb(struct PKTIO_HANDLE_Tag * channel, Ti_Pkt* p_recv[],
140                          PKTIO_METADATA_T meta[], int n_pkts,
141                          uint64_t ts )
143     return;
146 /* byte swap routine */
147 static unsigned int swap32 (unsigned int x)
149     unsigned int y;
151     y = (((x >> 24) & 0xff) <<  0) |
152         (((x >> 16) & 0xff) <<  8) |
153         (((x >>  8) & 0xff) << 16) |
154         (((x >>  0) & 0xff) << 24) ;
156     return (y);
160 void cleanup_sa_sp()
162     int slot, error=0;;
163     /* delete any offloaded rx SA's and policies */
164     /* and delete any offloaded tx SA's */
165     for (slot = 0;slot < 64;slot++)
166     {
167         if(globalDB.rx_sa[slot].in_use)
168         {
169             globalDB.rx_sa[slot].in_use = 0;
170             if(globalDB.rx_sa[slot].spAppId)
171             {
172                 netapi_secDelRxPolicy(netapi_handle,
173                               (NETCP_CFG_IPSEC_POLICY_T) globalDB.rx_sa[slot].spAppId,
174                               &error);
175                 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
176                 "cleanup_sa_sp: SP deleted: sp_app_id: 0x%x, slot: %d, error: %d\n", 
177                 globalDB.rx_sa[slot].spAppId, slot, error);
178             }
179             netapi_secDelSA(netapi_handle,
180                         NETCP_CFG_NO_INTERFACE,
181                         (NETCP_CFG_SA_T) globalDB.rx_sa[slot].saAppId,
182                         &error);
183             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
184                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
185                 globalDB.rx_sa[slot].saAppId, slot, error);
186             
187         }
188         if(globalDB.tx_sa[slot].in_use)
189         {
190             globalDB.tx_sa[slot].in_use = 0;
191             netapi_secDelSA(netapi_handle,
192                             NETCP_CFG_NO_INTERFACE,
193                            (NETCP_CFG_SA_T) globalDB.tx_sa[slot].saAppId,
194                             &error);
195             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
196                 "cleanup_sa_sp: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
197                 globalDB.tx_sa[slot].saAppId, slot, error);
198         }
199     }
203 static void* snoop_run_thread (void* arg)
205     ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
206         "snoop_run_thread: daemon entering forever event loop\n");
208     while (1)
209     {
210         /* Poll for message from user application */
211         ipsecmgr_ipc_poll();
213         /* Poll for message from Kernel */
214         ipsecmgr_snoop_run();
216         if (QUIT == 1)
217             break;
218     }
219     printf("snoop_run_thread: calling shutdown\n");
220     ipsecmgr_snoop_shutdown ();
221     cleanup_sa_sp();
222     netapi_shutdown(netapi_handle);
224     return;
227 /**
228  *  @b Description
229  *  @n  
230  *      SIGTERM handler.
231  *
232  *  @param[in]  signum
233  *      signal number to terminate deamon.
234  */
235 static void sig_term_handler(int signum)
237     QUIT = 1;
240 /**
241  *  @b Description
242  *  @n  
243  *      Function to implement task sleep functionality 
244  *      for IPSecMgr
245  *
246  *  @param[in]  time_in_msec
247  *      Time in milliseconds to sleep
248  *
249  *  @retval
250  *      Not Applicable.
251  */
252 static void task_sleep(uint32_t time_in_msec)
254     pthread_mutex_t fake_mutex = PTHREAD_MUTEX_INITIALIZER;
255     pthread_cond_t fake_cond = PTHREAD_COND_INITIALIZER;
256     struct timespec ts;
257     int rt;
258     unsigned int sec, nsec;
260     sec = time_in_msec/1000;
261     nsec = (time_in_msec - (sec*1000)) * 1000000;
263     /* Use the wall-clock time */
264     clock_gettime(CLOCK_REALTIME, &ts);
266     ts.tv_sec += sec;
267     ts.tv_nsec += nsec;
269     pthread_mutex_lock(&fake_mutex);
270     rt = pthread_cond_timedwait(&fake_cond, &fake_mutex, &ts);
271     pthread_mutex_unlock(&fake_mutex);
275 /**
276  *  @b Description
277  *  @n  
278  *      NETAPI Proxy's IPSecMgr Start Offload Response 
279  *      message handler.
280  *
281  *      This function is called by the IPSecMgr library
282  *      when it has a response ready corresponding to an
283  *      Start Offload SP request issued by the user application.
284  *
285  *  @param[in]  rsp
286  *      IPSecMgr's Start Offload SP response
287  *  @param[in]  addr
288  *      Destination address (user application) to send 
289  *      the response to
290  *  @param[in]  addr_size
291  *      Size of destination address passed
292  *
293  *  @retval
294  *      Success -   0
295  *  @retval
296  *      ERROR   -   <0
297  */
298 static int offload_sp_rsp_send
300     ipsecmgr_snoop_offload_sp_rsp_param_t *rsp,
301     void                                  *addr,
302     uint32_t                              addr_size
305     ipsecmgr_ipc_offload_sp_rsp_param_t offload_sp_rsp;
307     offload_sp_rsp.type = rsp->type;
308     offload_sp_rsp.result = rsp->result;
309     offload_sp_rsp.trans_id = rsp->trans_id;
310     offload_sp_rsp.err_code = rsp->err_code;
311     offload_sp_rsp.sp_handle = rsp->sp_handle;
312     offload_sp_rsp.sa_handle = rsp->sa_handle;
314     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
315         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
316             "offload_sp_rsp_send: addr size not correct\n");
317         return -1;
318     }
320     return send_iface->offload_sp_rsp(&offload_sp_rsp,
321                                       (ipsecmgr_ipc_addr_t *)addr);
323 static void offload_sp_req_recv
325     ipsecmgr_ipc_offload_sp_req_param_t *req,
326     ipsecmgr_ipc_addr_t                 *src_addr
329     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"offload_sp_req_recv called for policy id\n",
330     req->policy_id);
331     ipsecmgr_snoop_offload_sp_rsp_param_t rsp;
332     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
333     ipsecmgr_snoop_offload_sp_req_param_t offload_sp_req;
335     offload_sp_req.trans_id = req->trans_id;
336     offload_sp_req.policy_id = req->policy_id;
337     offload_sp_req.sa_flags = req->sa_flags;
338     offload_sp_req.if_name = req->if_name;
339     offload_sp_req.dscp_cfg = req->dscp_cfg;
340     offload_sp_req.l5_selector = req->l5_selector;
342     memset(&rsp, 0, sizeof(rsp));
343     rsp.trans_id = req->trans_id;
345     if (ipsecmgr_snoop_offload_sp_req(&offload_sp_req, (void*)src_addr,
346                                       addr_size)) {
347         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
348             "offload_sp_req_recv: snoop_offload_sp_req failed\n");
349         rsp.result = RESULT_FAILURE;
350         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
351     }
352     else
353     {
354         rsp.result = RESULT_SUCCESS;
355         rsp.type = RSP_TYPE_ACK;
356     }
357     
358     if (offload_sp_rsp_send(&rsp, (void *)src_addr, addr_size))
359     {
360         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
361             "offload_sp_req_recv: failed to send ACK for offload_sp\n");
362     }
363     return;
367 /**
368  *  @b Description
369  *  @n  
370  *      NETAPI Proxy's IPSecMgr Stop Offload response message 
371  *      handler.
372  *
373  *      This function is called by the IPSecMgr library
374  *      when it has a response ready corresponding to an
375  *      Stop Offload SP request issued by the user application.
376  *
377  *  @param[in]  rsp
378  *      IPSecMgr's Stop Offload SP response
379  *  @param[in]  addr
380  *      Destination address (user application) to send 
381  *      the response to
382  *  @param[in]  addr_size
383  *      Size of destination address passed
384  *
385  *  @retval
386  *      Success -   0
387  *  @retval
388  *      ERROR   -   <0
389  */
390 static int stop_offload_rsp_send
392     ipsecmgr_snoop_stop_offload_rsp_param_t *rsp,
393     void                                    *addr,
394     uint32_t                                addr_size
397     ipsecmgr_ipc_stop_offload_rsp_param_t stop_offload_rsp;
399     stop_offload_rsp.type = rsp->type;
400     stop_offload_rsp.result = rsp->result;
401     stop_offload_rsp.trans_id = rsp->trans_id;
403     if (addr_size != sizeof(ipsecmgr_ipc_addr_t)) {
404         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
405             "stop_offload_rsp_send: addr size not correct\n");
406         return -1;
407     }
409     return send_iface->stop_offload_rsp(&stop_offload_rsp,
410                                       (ipsecmgr_ipc_addr_t *)addr);
413 static void stop_offload_req_recv
415     ipsecmgr_ipc_stop_offload_req_param_t   *req,
416     ipsecmgr_ipc_addr_t                     *src_addr
419     ipsecmgr_snoop_stop_offload_req_param_t stop_offload_req;
420     uint32_t addr_size = sizeof(ipsecmgr_ipc_addr_t);
421     ipsecmgr_snoop_stop_offload_rsp_param_t rsp;
423     stop_offload_req.trans_id = req->trans_id;
424     stop_offload_req.policy_id = req->policy_id;
426     memset(&rsp, 0, sizeof(rsp));
427     rsp.trans_id = req->trans_id;
429     if (ipsecmgr_snoop_stop_offload(&stop_offload_req, (void*)src_addr,
430                                       addr_size)) {
431         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
432             "stop_offload_req_recv: snoop_stop_offload failed\n");
433         rsp.result = RESULT_FAILURE;
434         rsp.type = RSP_TYPE_ACK | RSP_TYPE_DONE;
435     }
436     else
437     {
438         rsp.result = RESULT_SUCCESS;
439         rsp.type = RSP_TYPE_ACK;
440     }
442     if (stop_offload_rsp_send(&rsp, (void *)src_addr, addr_size))
443     {
444         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
445             "stop_offload_req_recv: failed to send ACK for stop_offload\n");
446     }
447     return;
450 /**
451  *  @b Description
452  *  @n  
453  *      Function to initialize IPSec Manager library.
454  *
455  *  @retval
456  *      Success -   0
457  *  @retval
458  *      ERROR   -   >0
459  */
460 static int32_t init_ipsecmgr (void)
462     struct ipsecmgr_snoop_fp_cfg_cb     fp_cfg_cb;
463     struct ipsecmgr_snoop_mgnt_cb       mgnt_cb;
464     struct ipsecmgr_snoop_platform_cb   plat_cb;
465     ipsecmgr_ipc_daemon_recv_if_t       recv_if;
466     ipsecmgr_ipc_cfg_t                  ipc_cfg;
467     int32_t                             status;
468     pthread_attr_t threadAttr;
470     /* Initializations */
471     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, 
472                         "DEBUG: init_ipsecmgr() starting initialization\n");
473     memset(&fp_cfg_cb, 0, sizeof(fp_cfg_cb));
474     memset(&mgnt_cb, 0, sizeof(mgnt_cb));
475     memset(&plat_cb, 0, sizeof(plat_cb));
476     memset(&recv_if, 0, sizeof(recv_if));
477     memset(&ipc_cfg, 0, sizeof(ipc_cfg));
479     /* Initialize IPC library */
480     ipc_cfg.mode = IPC_MODE_SNOOP_DAEMON;
481     if (ipsecmgr_ipc_init(&ipc_cfg)) {
482         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
483             "init_ipsecmgr: ipc_init failed\n");
484         return -1;
485     }
486     else
487         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
488             "init_ipsecmgr: ipc_init sucess\n");
490     if (ipsecmgr_ipc_get_daemon_send_iface(&send_iface)) {
491         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
492             "init_ipsecmgr: ipc_get_daemon_send_iface failed\n");
493         return -1;
494     }
495     recv_if.offload_sp_req = offload_sp_req_recv;
496     recv_if.stop_offload_req = stop_offload_req_recv;
497     /* Register ipsecmgr daemon recieve i/f */
498     if (ipsecmgr_ipc_register_daemon_recv_iface(&recv_if)) {
499         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
500             "snoop_run: ipc_register_daemon_recv_iface failed\n");
501         return -1;
502     }
504     /* Initialize the IPSec Manager Snoop library */
505     fp_cfg_cb.add_sa        =   netapilib_ifAddSA;
506     fp_cfg_cb.add_sp        =   netapilib_ifAddSP;
507     fp_cfg_cb.del_sa        =   netapilib_ifDeleteSA;
508     fp_cfg_cb.del_sp        =   netapilib_ifDeleteSP;
509     fp_cfg_cb.get_sa_ctx    =   netapilib_ifGetSACtx;
511     plat_cb.log_msg  = (ipsecmgr_snoop_log_msg_t)ipsecmgr_syslog_msg;
512     plat_cb.sleep           =   task_sleep;
514     mgnt_cb.offload_sp_rsp  =   offload_sp_rsp_send;
515     mgnt_cb.stop_offload_rsp=   stop_offload_rsp_send;
516     mgnt_cb.rekey_event     =   NULL; // No explicit notifications needed on Rekey completion
518     if ((status = ipsecmgr_snoop_init (&fp_cfg_cb, &mgnt_cb, &plat_cb))) 
519     {
520         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
521                             "DEBUG: init_ipsecmgr() ipsecmgr_snoop_init failed (%d)\n", status);
522         return -1;
523     }
525     /* Create the task context for snoop library */
526     pthread_attr_init(&threadAttr);
527     pthread_attr_setstacksize(&threadAttr, 0x8000);
528     if (pthread_create(&snoop_run_th, (void*) NULL, snoop_run_thread, NULL))
529     {
530         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
531             "ERROR: snoop run thread failed to start, error code\n"); 
532         return -1;
533     }
535     /* Setup signal handler for SIGTERM */
536     if (signal(SIGTERM, sig_term_handler) == SIG_ERR) {
537         ipsecmgr_syslog_msg(SYSLOG_LEVEL_WARN,
538             "init_ipsecmgr: cannot handle SIGTERM\n");
539     }
540     /* Wait for the NETAPI Proxy task to finish its processing and exit. */
541     pthread_join (snoop_run_th, NULL);
543     return 0;
546 /**
547  *  @b Description
548  *  @n  
549  *      Utility function to daemonize the current
550  *      application.
551  *
552  *  @param[in]  lock_file
553  *      Lock file to be used by the daemon
554  */
555 static void daemonize (const char *lock_file)
557     pid_t       pid, sid;
558     int32_t     lock_fp = -1;
559     char        str[10];
561     /* already a daemon */
562     if (getppid () == 1)
563         return;
565     /* Fork off the parent process */
566     if ((pid = fork ()) < 0) 
567     {
568         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
569                             "ERROR: daemonize() unable to fork daemon, code=%d (%s)",
570                             errno, 
571                             strerror(errno));
572         exit (-1);
573     }
575     /* If we got a PID, then exit the parent process. */
576     if (pid > 0)
577         exit (0);
579     /* At this point we are executing as the child process */
581     /* Create a new SID for the child process */
582     if ((sid = setsid ()) < 0) 
583     {
584         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
585                             "ERROR: daemonize() unable to create a new session, code %d (%s)",
586                             errno, 
587                             strerror(errno));
588         exit (-1);
589     }
591     /* Change the file mode mask */
592     umask (027);
594     /* Change the current working directory.  This prevents the current
595      * directory from being locked; hence not being able to remove it. */
596     if ((chdir("/")) < 0) 
597     {
598         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR, 
599                             "ERROR: daemonize() unable to change directory to %s, code %d (%s)",
600                             "/", 
601                             errno, 
602                             strerror(errno));
603         exit (-1);
604     }
606     /* Create the lock file */
607     if (lock_file) 
608     {
609         if ((lock_fp = open(lock_file, O_RDWR|O_CREAT, 0640)) < 0 ) 
610         {
611             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
612                                 "ERROR: daemonize() unable to create lock file %s, code=%d (%s)",
613                                 lock_file, 
614                                 errno, 
615                                 strerror(errno));
616             exit (-1);
617         }
618     }
620     if (lockf (lock_fp, F_TLOCK, 0) < 0) 
621         exit(-1); /* can not lock */
623     /* Record pid to lockfile */
624     sprintf (str, "%d\n", getpid());
625     write (lock_fp, str, strlen(str)); 
627     /* Cancel certain signals */
628     signal (SIGCHLD, SIG_DFL); /* A child process dies */
629     signal (SIGTSTP, SIG_IGN); /* Various TTY signals */
630     signal (SIGTTOU, SIG_IGN);
631     signal (SIGTTIN, SIG_IGN);
632     signal (SIGHUP, SIG_IGN); /* Ignore hangup signal */
633     signal (SIGTERM, sig_term_handler); /* catch SIGTERM */
635     /* Redirect standard files to /dev/null */
636     freopen( "/dev/null", "r", stdin);
637     freopen( "/dev/null", "w", stdout);
638     freopen( "/dev/null", "w", stderr);
640     /* Done setting up the daemon */
641     return;
644 /* FUNCTION PURPOSE:validate and process inputs to the application */
645 int32_t parse_cmd_line_args(int argc, char** argv)
647     int32_t             i;
649     /* Valid command line options */
650     if (argc == 1)
651     {
652         printf("netapi_proxyParseCommandLineArgs, argc =1\n");
653         return 0;
654     }
655     else
656     {
657            printf("netapi_proxyParseCommandLineArgs, argc=%d\n", argc);
658      
659     }
661     /* Scan and parse the command line options */
662     for (i = 1; i < argc; i ++)
663     {
664         if (argv[i][0] == '-' && argv[i][1] == 'f')
665         {
666             /* Log file name */                
667             if (i+1 >= argc || argv[i+1] == NULL)
668                 return -1;
669             i++;
670         }
671         else
672         {
673             /* Invalid options */
674             return -1;
675         }
676     }
677     /* Success */
678     return 0;
681 int get_kernel_config(int index)
683     uint32_t temp=0;
684     FILE *pDts = NULL;
686     pDts = fopen(DTS_LOG_FILE_QUEUE_ETHx[index], "rb");
688     if(pDts)
689     {
690         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
691         globalDB.qNum[index]= (int)swap32(temp);
692         fclose(pDts);
693     }
694     else
695     {
696         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
697             "main: error opening device tree file: %s\n",DTS_LOG_FILE_QUEUE_ETHx[index]);
698         return -1;
699     }
701     pDts = NULL;
702     pDts = fopen(DTS_LOG_FILE_FLOW_ETHx[index], "rb");
704     if(pDts)
705     {
706         fread((void*)&temp, sizeof(uint32_t), 1, pDts);
707         globalDB.flowId[index] = (int)swap32(temp);
708         fclose(pDts);
709     }
710     else
711     {
712         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
713             "main: error opening device tree file: %s\n",DTS_LOG_FILE_FLOW_ETHx[index]);
714         return -1;
715     }
716     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
717             "get_kernel_config(%d): flow: 0x%x, qNum: 0x%x\n", 
718                     index, globalDB.flowId[index], globalDB.qNum[index]);
719     return 0;
722 int create_pktio_channel(int index)
724     int error = 0;
725     char name[19];
726     PKTIO_HANDLE_T *pktio_channel;
727     PKTIO_CFG_T pktio_cfg;
729         memset(&pktio_cfg,0,sizeof(PKTIO_CFG_T));
731         sprintf(&name[0],"%s%d","offload_", index);
732         pktio_cfg.qnum = globalDB.qNum[index];
733         pktio_cfg.flags1 = PKTIO_RX;
734         pktio_cfg.flags2 = PKTIO_GLOBAL | PKTIO_PKT;
735         pktio_cfg.max_n = 8;
737         globalDB.pktio_channel[index] = netapi_pktioCreate(netapi_handle,
738                                                    &name[0],
739                                                    (PKTIO_CB)recv_cb,
740                                                    &pktio_cfg,
741                                                    &error);
742         if (!globalDB.pktio_channel[index])
743         {
744             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
745                 "create_pktio_channel: failed\n");
746             return -1;
747         }
748         else
749         {
750             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
751             "created pktio channel for queue :0x%x\n", globalDB.qNum[index]);
752         }
753     return 0;
755 /**
756  *  @b Description
757  *  @n  
758  *      Entry point for the NETAPI Proxy application.
759  *
760  *  @param[in]  argc
761  *      Number of arguments passed to the application
762  *  @param[in]  argv
763  *      Arguments passed to the application.
764  *
765  *  @retval
766  *      Success -   0
767  *  @retval
768  *      ERROR   -   >0
769  */
770 int32_t main (int argc, char* argv[])
772     int32_t             retVal;
773     int i, iface;
774     char* pTok = NULL;
775     int ip_entry_count = 0;
776     struct ifaddrs *ifaddr, *ifa;
777            int family, s;
778            char host[NI_MAXHOST];
779            char sa_data[14];
780     ipsecmgr_syslog_init();
782     memset(&globalDB, 0, sizeof(globalDB));
783     memset(&ipConfigList, 0, sizeof(ipConfigList));
784     /* create netapi */
785     netapi_handle = netapi_init(NETAPI_SYS_MASTER, &our_netapi_default_cfg);
787     if(netapi_handle == NULL)
788     {
789         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, "ERROR: netapi_init failed\n");
790         return -1;
791     }
792     else
793         netapi_netcpCfgExceptions(netapi_handle, NETCP_CFG_ALL_EXCEPTIONS, NETCP_CFG_ACTION_DISCARD, (NETCP_CFG_ROUTE_HANDLE_T) NULL);
795     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, "ERROR: netapi_init failed\n");
798     for (i = 0; i < 16; i++)
799     {
800         if (get_kernel_config(i))
801         {
802             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
803                                 "ERROR: main: get_kernel_config() failed\n");
804             continue;
805         }
806         else
807         {
808             /* create pktio channel */
809             if(create_pktio_channel(i))
810             {
811                 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
812                                 "ERROR: main: pktio channel creation failed\n");
813             }
814         }
815     }
816     /* Read and parse command line options */
817     if (parse_cmd_line_args (argc, argv) < 0)
818     {
819         printf ("Usage format: netfpproxy.out [-f <log_file>]\n");
820         return -1;
821     }
822     printf("main: calling daemonize\n");
824     /* Create the proxy daemon. */
825     //daemonize (LOCK_FILE);
827     if (getifaddrs(&ifaddr) == -1)
828     {
829         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
830                                 "main: getifaddrs failure\n");
831         return -1;
832     }
834     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
835     {
836         if (ifa->ifa_addr == NULL)
837             continue;
839         family = ifa->ifa_addr->sa_family;
841         if (family == AF_INET)
842         {
843             s = getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in),
844                             host,
845                             NI_MAXHOST,
846                             NULL,
847                             0,
848                             NI_NUMERICHOST); 
849             if (s != 0)
850             {
851                 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
852                     "getnameinfo() failed: %s\n", gai_strerror(s));
853                     continue;
854             }
855             for (i=0;i<4;i++)
856             {
857                 ipConfigList[ip_entry_count].ip[i] = ifa->ifa_addr->sa_data[i+2];
858             }
859             memcpy(&ipConfigList[ip_entry_count].name[0],
860                     ifa->ifa_name,
861                     strlen(ifa->ifa_name));
862             pTok = strtok(ifa->ifa_name, ":.");
863             /* now we have the interface name, is this eth0 or eth1 */
864             if (pTok)
865             {
866                 if(strstr(pTok,"eth"))
867                 {
868                     sscanf(pTok,"eth%d", &iface);
869                     ipConfigList[ip_entry_count].iface = iface;
870                 }
871                 else
872                 {
873                     ipConfigList[ip_entry_count].iface = -1;
874                 }
875                 ip_entry_count++;
876             }
877         }
878     }
880     if (ifaddr)
881         freeifaddrs(ifaddr);
883     /* Initialize and start the IPSec Mgr Snoop functionality */
884     if ((retVal = init_ipsecmgr ()) < 0)
885     {
886         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
887                             "ERROR: IPSec Mgr init failed, error code %d \n",
888                             retVal);
889         return -1;
890     }
891     else
892         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
893                              "main: ipsecmgr daemon shutdonw complete\n");