07ccd673b70aa382fceb7449292c1caca04b9c86
[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=
140 {
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 )
162 {
163 return;
164 }
166 /* byte swap routine */
167 static unsigned int swap32 (unsigned int x)
168 {
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);
178 }
180 void cleanup_sa_sp()
181 {
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);
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 }
220 }
223 static void* snoop_run_thread (void* arg)
224 {
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;
252 }
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)
263 {
264 QUIT = 1;
265 }
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)
280 {
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);
299 }
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
326 (
327 ipsecmgr_snoop_offload_sp_rsp_param_t *rsp,
328 void *addr,
329 uint32_t addr_size
330 )
331 {
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);
349 }
350 static void offload_sp_req_recv
351 (
352 ipsecmgr_ipc_offload_sp_req_param_t *req,
353 ipsecmgr_ipc_addr_t *src_addr
354 )
355 {
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 }
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;
392 }
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
419 (
420 ipsecmgr_snoop_stop_offload_rsp_param_t *rsp,
421 void *addr,
422 uint32_t addr_size
423 )
424 {
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);
439 }
441 static void stop_offload_req_recv
442 (
443 ipsecmgr_ipc_stop_offload_req_param_t *req,
444 ipsecmgr_ipc_addr_t *src_addr
445 )
446 {
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;
476 }
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)
489 {
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;
577 }
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)
589 {
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 sprintf (str, "%d\n", getpid());
658 write (lock_fp, str, strlen(str));
660 /* Cancel certain signals */
661 signal (SIGCHLD, SIG_DFL); /* A child process dies */
662 signal (SIGTSTP, SIG_IGN); /* Various TTY signals */
663 signal (SIGTTOU, SIG_IGN);
664 signal (SIGTTIN, SIG_IGN);
665 signal (SIGHUP, SIG_IGN); /* Ignore hangup signal */
666 signal (SIGTERM, sig_term_handler); /* catch SIGTERM */
668 /* Redirect standard files to /dev/null */
669 freopen( "/dev/null", "r", stdin);
670 freopen( "/dev/null", "w", stdout);
671 freopen( "/dev/null", "w", stderr);
673 /* Done setting up the daemon */
674 return;
675 }
677 int get_kernel_config()
678 {
679 uint32_t temp=0;
680 FILE *pDts = NULL;
682 pDts = fopen(DTS_LOG_FILE_QUEUE_ETHx[0], "rb");
684 if(pDts)
685 {
686 fread((void*)&temp, sizeof(uint32_t), 1, pDts);
687 globalDB.qNum = (int)swap32(temp);
688 fclose(pDts);
689 }
690 else
691 {
692 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
693 "main: error opening device tree file: %s\n",DTS_LOG_FILE_QUEUE_ETHx[0]);
694 return -1;
695 }
697 pDts = NULL;
698 pDts = fopen(DTS_LOG_FILE_FLOW_ETHx[0], "rb");
700 if(pDts)
701 {
702 fread((void*)&temp, sizeof(uint32_t), 1, pDts);
703 globalDB.flowId = (int)swap32(temp);
704 fclose(pDts);
705 }
706 else
707 {
708 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
709 "main: error opening device tree file: %s\n",DTS_LOG_FILE_FLOW_ETHx[0]);
710 return -1;
711 }
712 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
713 "get_kernel_config: flow: 0x%x, qNum: 0x%x\n",
714 globalDB.flowId, globalDB.qNum);
715 return 0;
716 }
718 int create_pktio_channel()
719 {
720 static int count = 0;
721 int error = 0;
722 char name[19];
723 PKTIO_HANDLE_T *pktio_channel;
724 PKTIO_CFG_T pktio_cfg;
725 NETCP_CFG_ROUTE_T route;
726 NETCP_CFG_FLOW_T flow;
727 NETCP_CFG_EXCEPTION_PKT_T expPkt_appid = 0;
729 memset(&pktio_cfg,0,sizeof(PKTIO_CFG_T));
730 memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
731 memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
733 sprintf(&name[0],"%s","offload_0");
734 pktio_cfg.qnum = globalDB.qNum;
735 pktio_cfg.flags1 = PKTIO_RX;
736 pktio_cfg.flags2 = PKTIO_GLOBAL | PKTIO_PKT;
737 pktio_cfg.max_n = 8;
738 pktio_cfg.queueType = Qmss_QueueType_GIC400_QUEUE;
740 globalDB.pktio_channel = netapi_pktioCreate(netapi_handle,
741 &name[0],
742 (PKTIO_CB)recv_cb,
743 &pktio_cfg,
744 &error);
745 if (!globalDB.pktio_channel)
746 {
747 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
748 "create_pktio_channel: failed\n");
749 return -1;
750 }
753 flow.dma_engine= 1;
754 flow.flowid = globalDB.flowId;
755 route.p_dest_q = globalDB.pktio_channel;
756 route.p_flow = &flow;
757 route.valid_params |= NETCP_CFG_VALID_PARAM_ROUTE_TYPE;
758 route.routeType = NWAL_ROUTE_RX_INTF_W_FLOW;
759 /* enable exception packet handling for fragmented packets */
760 expPkt_appid = netapi_netcpCfgExceptions(netapi_handle,
761 7,
762 NETCP_CFG_ACTION_TO_SW,
763 (NETCP_CFG_ROUTE_HANDLE_T) &route);
765 return 0;
766 }
767 /**
768 * @b Description
769 * @n
770 * Entry point for the NETAPI Proxy application.
771 *
772 * @param[in] argc
773 * Number of arguments passed to the application
774 * @param[in] argv
775 * Arguments passed to the application.
776 *
777 * @retval
778 * Success - 0
779 * @retval
780 * ERROR - >0
781 */
782 int32_t main (int argc, char* argv[])
783 {
784 int32_t retVal;
785 int i, iface;
786 char* pTok = NULL;
787 int ip_entry_count = 0;
788 struct ifaddrs *ifaddr, *ifa;
789 int family, s;
790 char host[NI_MAXHOST];
791 struct sockaddr_in6 ipv6_addr;
792 cpu_set_t cpu_set;
793 int c;
794 static char usage[] = "usage: %s -r < use Resource manager: no/yes> -s <outbound sequence number> -f <SA transmit flow Id>\n";
796 ipsecmgr_syslog_init();
799 memset(&globalDB, 0, sizeof(globalDB));
800 globalDB.sa_tx_flow = -1;
801 int temp;
802 while ((c = getopt (argc, argv, "s:f:r:")) != -1)
803 {
804 switch (c)
805 {
806 case 'r':
807 if(strncmp("yes", optarg,1) == 0)
808 {
809 use_rm = 1;
810 }
811 break;
813 case 's':
814 /* check is user input 0 for oseq_offset (valid but also default)*/
815 if(strncmp("0", optarg,1) == 0)
816 {
817 globalDB.oseq_offset = 0;
818 }
819 else
820 {
821 globalDB.oseq_offset = (uint32_t)strtol(optarg, NULL,0);
822 if(!globalDB.oseq_offset)
823 {
824 printf(usage, argv[0]);
825 exit(EXIT_FAILURE);
826 }
827 }
828 break;
829 case 'f':
830 /* check is user input 0 for sa_tx_flow(valid) */
831 if(strncmp("0", optarg,1) == 0)
832 {
833 globalDB.sa_tx_flow= 0;
834 }
835 else
836 {
837 globalDB.sa_tx_flow = (uint32_t)strtol(optarg, NULL,0);
838 if(!globalDB.sa_tx_flow)
839 {
840 printf(usage, argv[0]);
841 exit(EXIT_FAILURE);
842 }
843 }
844 break;
845 case '?':
846 printf(usage, argv[0]);
847 exit(EXIT_FAILURE);
848 default:
849 break;
850 }
851 }
852 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
853 "main: oseq_offset: %d, sa_tx_flow: %d\n",
854 globalDB.oseq_offset, globalDB.sa_tx_flow);
856 if (use_rm)
857 {
858 if (initRm())
859 {
860 exit(EXIT_FAILURE);
861 }
862 }
864 /* assign main net_test thread to run on core 0 */
865 CPU_ZERO( &cpu_set);
866 CPU_SET( 0, &cpu_set);
867 hplib_utilSetupThread(0, &cpu_set, hplib_spinLock_Type_LOL);
868 /* create netapi */
869 our_netapi_default_cfg.rmHandle = rmClientServiceHandle;
870 netapi_handle = netapi_init(NETAPI_SYS_MASTER,
871 &our_netapi_default_cfg);
872 if(netapi_handle == NULL)
873 {
874 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
875 "ERROR: netapi_init failed\n");
876 return -1;
877 }
878 else
879 netapi_netcpCfgExceptions(netapi_handle,
880 NETCP_CFG_ALL_EXCEPTIONS,
881 NETCP_CFG_ACTION_DISCARD,
882 (NETCP_CFG_ROUTE_HANDLE_T) NULL);
884 if (get_kernel_config())
885 {
886 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
887 "ERROR: main: get_kernel_config() failed\n");
888 return -1;
889 }
890 else
891 {
892 /* create pktio channel */
893 if(create_pktio_channel())
894 {
895 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
896 "ERROR: main: pktio channel creation failed\n");
897 return -1;
898 }
899 }
900 /*Create the proxy daemon. */
901 ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO, "main: calling daemonize\n");
902 daemonize (LOCK_FILE);
904 /* Initialize and start the IPSec Mgr Snoop functionality */
905 if ((retVal = init_ipsecmgr ()) < 0)
906 {
907 ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
908 "ERROR: IPSec Mgr init failed, error code %d \n",
909 retVal);
910 return -1;
911 }
912 else
913 ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
914 "main: ipsecmgr daemon shutdonw complete\n");
916 exit(EXIT_SUCCESS);
918 }