37259234211abd5a805d38865451b01174bfa359
[keystone-rtos/netapi.git] / ti / runtime / netapi / applications / ipsec_offload / ipsecmgr / src / netapilib_interface.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 */
35 /* Standard includes */
36 #include <stdio.h>
37 #include <arpa/inet.h>
38 #include <inttypes.h>
40 /* ipsecmgr includes */
41 #include <ipsecmgr_snoop.h>
42 #include <ipsecmgr_syslog.h>
44 #include "netapilib_interface.h"
47 extern ipsecMgrMcb_t globalDB;
48 extern NETAPI_T netapi_handle;
50 /**************************************************************************
51  * FUNCTION PURPOSE:  Internal function to find a free slot to store APPID
52  *                    in list
53  **************************************************************************
54  * DESCRIPTION:  Internal internal function to find a free slot in SA list for an SA
55  ********************************************************************/
56 int findFreeAppIdSlot(ipsecMgrAppId_T *pList)
57 {
58     int i;
59     for(i=0;i<64;i++)
60     {                       
61         if (!pList[i].in_use)
62         {
63             if (free)
64             pList[i].in_use = 1; //pending
65             return i;
66         }
67     }
68     return -1;
69 }
71 /********************************************************************
72  * FUNCTION PURPOSE:  Internal function to find a SA app id  in SA list
73  *                    and free SA Slot entry if specified
74  ********************************************************************
75  * DESCRIPTION:  Internal function to find a SA app id  in SA list
76  *                    and free SA Slot entry if specified
77  ********************************************************************/
78 int findAppIdSlot(ipsecMgrAppId_T *pList, uint32_t saAppId, int free)
79 {
80     int i;
81     for(i=0;i<64;i++)
82     {                       
83         if ((pList[i].in_use) && (pList[i].saAppId == saAppId))
84         {
85             if(free)
86                 pList[i].in_use = 0;
87             return i;
88         }
89     }
90     return -1;
91 }
93 /**************************************************************************
94  * FUNCTION PURPOSE: The function is used to translate the SA configuration
95  * parameters received from the IPSec Snopper and call the NETAPI function
96  * to create a security association
97  ********************************************************************/
98 int netapilib_ifAddSA
99 (
100     ipsecmgr_af_t               af,
101     ipsecmgr_sa_id_t            *sa_id,
102     ipsecmgr_sa_info_t          *sa_info,
103     ipsecmgr_sa_dscp_map_cfg_t  *dscp_map_cfg,
104     ipsecmgr_ifname_t           *if_name,
105     ipsecmgr_sa_encap_tmpl_t    *encap,
106     ipsecmgr_fp_handle_t        *sa_handle
109     int i;
110     uint8_t                 auth_key[36];
111     uint8_t                 encr_key[36];
112     int error, index,slot;
113     NETAPI_SEC_SA_INFO_T saInfo;
114     nwalSecKeyParams_t  keyParams;
115     void * p_rx_inflow_mode_handle;
116     void * p_tx_inflow_mode_handle;
117     NETCP_CFG_ROUTE_T  route;
118     NETCP_CFG_FLOW_T flow;
119     NETCP_CFG_SA_HANDLE_T pSaHandle;
120     char* pTok = NULL;
121     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO, 
122                 "netapilib_ifAddSA:, DEBUG: Translating SA\n");
124     memset((void *)&saInfo, 0, sizeof (NETAPI_SEC_SA_INFO_T));
125     memset((void *)&keyParams, 0, sizeof (nwalSecKeyParams_t));
126     memset((void *)&route, 0, sizeof (NETCP_CFG_ROUTE_T));
127     memset((void *)&flow, 0, sizeof (NETCP_CFG_FLOW_T));
129     /* Initialize the SA Config structure. */
130     /* Get the IP protocol version. */
131     if (af == IPSECMGR_AF_IPV4)
132     {
133         saInfo.ipType = nwal_IPV4;
134         /* Populate the source and destination IP addresses. */
135         for (index = 0; index < NWAL_IPV4_ADDR_SIZE; index++)
136         {
137             saInfo.dst.ipv4[index] = sa_id->daddr.ipv4[index];
138             saInfo.src.ipv4[index] = sa_info->saddr.ipv4[index];
139         }
140     }
141     else if (af == IPSECMGR_AF_IPV6)
142     { 
143         saInfo.ipType = nwal_IPV6;
145         /* Populate the source and destination IP addresses. */
146         for (index = 0; index < NWAL_IPV6_ADDR_SIZE; index++)
147         {
148             saInfo.dst.ipv6[index] = sa_id->daddr.ipv6[index];
149             saInfo.src.ipv6[index] = sa_info->saddr.ipv6[index];
150         }
151     }
152     else
153     {
154         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
155             "netapilib_ifAddSA: Address family (%d) is invalid\n", af);
156         return -1;
157     }
158     /* Get the SPI. */
159     saInfo.spi = sa_id->spi;
161     /* Get the SA direction. */
162     if (sa_info->dir == DIR_INBOUND)
163     {
164         slot = findFreeAppIdSlot(&globalDB.rx_sa[0]);
165         if (slot == -1)
166         {
167             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
168                 "netapilib_ifAddSA:, Too many INBOUND SAs already offloaded\n");
169             return -1;
170         }
171         saInfo.dir = NWAL_SA_DIR_INBOUND;
173         flow.dma_engine= 1;
174         flow.flowid = globalDB.flowId;
175         ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
176                            "add_sa:flowid: %d\n",flow.flowid);
178         route.p_flow = &flow;
179         route.p_dest_q = globalDB.pktio_channel;
181         ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
182                        "add_sa: p_dest_q: 0x%x, flowId: 0x%x\n",
183                        route.p_dest_q,
184                        route.p_flow->flowid);
185        route.valid_params |= NETCP_CFG_VALID_PARAM_ROUTE_TYPE;
186        route.routeType = NWAL_ROUTE_RX_INTF_W_FLOW;
187     }
188     else if (sa_info->dir == DIR_OUTBOUND)
189     {
190         slot = findFreeAppIdSlot(&globalDB.tx_sa[0]);
191         if (slot == -1)
192         {
193             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
194                 "netapilib_ifAddSA:, Too many OUTBOUND SAs already offloaded\n");
195             return -1;
196         }
197         saInfo.dir = NWAL_SA_DIR_OUTBOUND;
198     }
199     else
200     {
201         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
202             "netapilib_ifAddSA: IPSec direction (%d) is invalid\n", sa_info->dir);
203         return -1;
204     }
205     
207     /* Get the replay Window */
208     saInfo.replayWindow = sa_info->replay_window;
209    
210     /* Get the IPSec protocol. */
211     if (sa_id->proto == SA_PROTO_AH)
212         saInfo.proto = nwal_IpSecProtoAH;
213     else if (sa_id->proto == SA_PROTO_ESP)
214         saInfo.proto = nwal_IpSecProtoESP;
215     else
216     {
217         ipsecmgr_syslog_msg(SYSLOG_LEVEL_INFO,
218             "netapilib_ifAddSA: IPSec protocol (%d) is invalid.\n", sa_id->proto);
219         return -1;
220     }
221     /* Get the IPSec mode. */
222     if (sa_info->mode == SA_MODE_TRANSPORT)
223         saInfo.saMode = nwal_SA_MODE_TRANSPORT;
224     else if (sa_info->mode == SA_MODE_TUNNEL)
225         saInfo.saMode = nwal_SA_MODE_TUNNEL;
226     else
227     {
228         ipsecmgr_syslog_msg(SYSLOG_LEVEL_ERROR,
229             "netapilib_ifAddSA: IPSec mode (%d) is invalid.\n", sa_info->mode);
230         return -1;
231     }
232     /* Get the authentication mode algorithm. */
233     if (sa_info->auth.algo == SA_AALG_HMAC_SHA1)
234         saInfo.authMode = NWAL_SA_AALG_HMAC_SHA1;
235     else if (sa_info->auth.algo == SA_AALG_HMAC_MD5)
236         saInfo.authMode = NWAL_SA_AALG_HMAC_MD5;
237     else if (sa_info->auth.algo == SA_AALG_AES_XCBC)
238         saInfo.authMode = NWAL_SA_AALG_AES_XCBC;
239     else if (sa_info->auth.algo == SA_AALG_HMAC_SHA2_256)
240         saInfo.authMode = NWAL_SA_AALG_HMAC_SHA2_256;
241     else if (sa_info->auth.algo == SA_AALG_NONE || sa_info->auth.algo == SA_AALG_NULL)  
242         saInfo.authMode = NWAL_SA_AALG_NULL;
243     else
244     {
245         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
246             "netapilib_ifAddSA: Authentication algorithm (%d) is invalid\n", sa_info->auth.algo);
247         return -1;
248     }
250     /* Get the encryption mode algorithm. */
251     if (sa_info->enc.algo == SA_EALG_NULL) 
252         saInfo.cipherMode = NWAL_SA_EALG_NULL;
253     else if (sa_info->enc.algo == SA_EALG_AES_CTR) 
254         saInfo.cipherMode = NWAL_SA_EALG_AES_CTR;
255     else if (sa_info->enc.algo == SA_EALG_AES_CBC)
256         saInfo.cipherMode = NWAL_SA_EALG_AES_CBC;
257     else if (sa_info->enc.algo == SA_EALG_3DES_CBC) 
258         saInfo.cipherMode = NWAL_SA_EALG_3DES_CBC;
259     else if (sa_info->enc.algo == SA_EALG_DES_CBC) 
260         saInfo.cipherMode = NWAL_SA_EALG_DES_CBC;
261     else
262     {
263         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
264             "netapilib_ifAddSA: Encryption algorithm (%d) is invalid\n", sa_info->enc.algo);
265         return -1;
266     }
267     /* Validate the key lengths. */
268     if ((keyParams.macKeySize = sa_info->auth_key_len) > 32)
269     {
270         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
271             "netapilib_ifAddSA: Authentication key size (%d) is invalid.\n", sa_info->auth_key_len);
272         return -1;
273     }
274     if ((keyParams.encKeySize = sa_info->enc_key_len) > 32)
275     {
276         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
277             "netapilib_ifAddSA: Encryption key size (%d) is invalid.\n", sa_info->enc_key_len);
278         return -1;
279     }
281     /* Get the authentication/encryption keys. */
282     keyParams.pAuthKey = &sa_info->auth_key[0];
283     keyParams.pEncKey = &sa_info->enc_key[0];
285     if (saInfo.dir == NWAL_SA_DIR_INBOUND)
286     {
287         /* Inbound == RX */
288         globalDB.rx_sa[slot].saAppId =  netapi_secAddSA(netapi_handle,
289                         NETCP_CFG_NO_INTERFACE,
290                         &saInfo,
291                         &keyParams,
292                         NETAPI_SEC_SA_INFLOW,
293                         (NETCP_CFG_ROUTE_HANDLE_T)&route,
294                         &p_rx_inflow_mode_handle,
295                         &p_tx_inflow_mode_handle,
296                         NULL, &error);
298         if (error == NETAPI_ERR_OK)
299         {
300             *sa_handle = globalDB.rx_sa[slot].saAppId;
301         }
302         else
303         {
304             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
305                                 "netapilib_ifAddSA: netapi_secAddSA returned error: %d.\n",
306                                  error);
307             return -1;
308         }
309     }
310     else
311     {
312         saInfo.esnLo = sa_info->esnlo + globalDB.oseq_offset;
314         /* OUTBOUND == TX */
315         globalDB.tx_sa[slot].saAppId = netapi_secAddSA(netapi_handle,
316                         NETCP_CFG_NO_INTERFACE,
317                         &saInfo,
318                         &keyParams,
319                         NETAPI_SEC_SA_INFLOW,
320                         (NETCP_CFG_ROUTE_HANDLE_T)NULL,
321                         &p_rx_inflow_mode_handle,
322                         &p_tx_inflow_mode_handle,
323                         NULL, &error);
324         if (error == NETAPI_ERR_OK)
325         {
326             *sa_handle = globalDB.tx_sa[slot].saAppId;
327         }
328         else
329         {
330             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
331                                 "netapilib_ifAddSA: netapi_secAddSA returned error: %d.\n",
332                                  error);
333             return -1;
334         }
335     }
336     
337     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
338     "netapilib_ifAddSA: Translation of SA successful, app_id: 0x%x\n", *sa_handle);
340     /* SA was created successfully. */
341     return 0;
344 /**************************************************************************
345  * FUNCTION PURPOSE: The function is used to translate the SA configuration
346  * parameters received from the IPSec Snopper and call the NETAPI function
347  * to delete a security association
348  ********************************************************************/
349 int netapilib_ifDeleteSA (ipsecmgr_fp_handle_t sa_handle)
351     int error, slot;
353     slot = findAppIdSlot(&globalDB.rx_sa[0],sa_handle, 1);
355     /* Determine if rx_sa or tx_sa is being deleted */
356     if (slot != -1)
357     {
358         /* found rx SA, see if there is policy assoicated with rx SA
359            if so, then delete it first*/
360         if (globalDB.rx_sa[slot].spAppId)
361         {    
362             netapi_secDelRxPolicy(netapi_handle,
363                               (NETCP_CFG_IPSEC_POLICY_T) globalDB.rx_sa[slot].spAppId,
364                               &error);
365             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
366                 "netapilib_ifDeleteSA: SP deleted: sp_app_id: 0x%x, slot: %d, error: %d\n", 
367                 globalDB.rx_sa[slot].spAppId, slot, error);
368             netapi_secDelSA(netapi_handle,
369                         NETCP_CFG_NO_INTERFACE,
370                         (NETCP_CFG_SA_T) sa_handle,
371                         &error);
372             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
373                 "netapilib_ifDeleteSA: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
374                 sa_handle, slot, error);
375             
376         }
377     }
378     else
379     {
380         /* not rx SA, check for tx_sa */
381         slot = findAppIdSlot(&globalDB.tx_sa[0], sa_handle, 1);
382     
383         if (slot != -1)
384         {
385             /* found tx SA, delete it now */
386             netapi_secDelSA(netapi_handle,
387                         NETCP_CFG_NO_INTERFACE,
388                         (NETCP_CFG_SA_T) sa_handle,
389                         &error);
390             ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
391                 "netapilib_ifDeleteSA: SA deleted: sa_app_id: 0x%x, slot: %d, error: %d\n", 
392                 sa_handle, slot, error);
393         }
394         else
395         {
396             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
397             "netapilib_ifDeleteSA: sa_app_id 0x%x not found in internal list\n", 
398                 sa_handle);
399             return -1;
400         }
401     }
403     return error;
406 /**************************************************************************
407  * FUNCTION PURPOSE: The function is used to translate the SP configuration
408  * parameters received from the IPSec Snopper and call the NETAPI function
409  * to create a security policy
410  ********************************************************************/
411 int32_t netapilib_ifAddSP
413     ipsecmgr_af_t           af,
414     ipsecmgr_selector_t     *sel,
415     ipsecmgr_dir_t          dir,
416     uint32_t                reqid,
417     ipsecmgr_fp_handle_t    sa_handle, 
418     ipsecmgr_policy_id_t    policy_id,
419     ipsecmgr_fp_handle_t    *sp_handle
422 #ifdef ENABLE_ADD_POLICY
423 #warning "ENABLE_ADD_POLICY"
424     NETCP_CFG_IPSEC_POLICY_T spAppIdIn;
425     int error, index, slot;
426     nwal_IpType ipType;
427     nwalIpAddr_t src_ip_addr;
428     nwalIpAddr_t dst_ip_addr;
429     nwalIpOpt_t ip_qualifiers;
430     NETCP_CFG_SA_T sa =(NETCP_CFG_SA_T)sa_handle;
431     NETCP_CFG_ROUTE_T  route;
432     NETCP_CFG_FLOW_T flow;
433     NETCP_CFG_PA_HANDLE_T pPaHandleOuterIP;
434     NETCP_CFG_PA_HANDLE_T pPaHandleInnerIP;
435     NETCP_CFG_SA_HANDLE_T pSaHandle;
437     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"netapilib_ifAddSP: called\n");
440     if (dir == DIR_OUTBOUND)
441     {
442         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
443             "netapilib_ifAddSP: called for outbound SA, no RX policy required\n");
444         return 0;
445     }
446     slot = findAppIdSlot(&globalDB.rx_sa[0],sa_handle, 0);
447     if (slot == -1)
448     {
449         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR, 
450             "netapilib_ifAddSA:, SA app_id not found\n");
451         return -1;
452     }
456     flow.dma_engine= 1;
457     flow.flowid = globalDB.flowId;
458     route.p_flow = &flow;
459     route.p_dest_q = globalDB.pktio_channel;
462     /* Get the IP protocol version. */
463     if (af == IPSECMGR_AF_IPV4)
464     {
465         ipType = nwal_IPV4;
466         /* Populate the source and destination IP addresses. */
467         for (index = 0; index < NWAL_IPV4_ADDR_SIZE; index++)
468         {
469             dst_ip_addr.ipv4[index] = sel->daddr.ipv4[index];
470             src_ip_addr.ipv4[index] = sel->saddr.ipv4[index];
471         }
472     }
473     else if (af == IPSECMGR_AF_IPV6)
474     { 
475         ipType = nwal_IPV6;
476         /* Populate the source and destination IP addresses. */
477         for (index = 0; index < NWAL_IPV6_ADDR_SIZE; index++)
478         {
479             dst_ip_addr.ipv6[index] = sel->daddr.ipv6[index];
480             src_ip_addr.ipv6[index] = sel->saddr.ipv6[index];
481         }
482     }
483     else
484     {
485         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
486             "netapilib_ifAddSP: Address family (%d) is invalid\n", af);
487         return -1;
488     }
490     globalDB.rx_sa[slot].spAppId = netapi_secAddRxPolicy(netapi_handle,
491                                      (NETCP_CFG_SA_T) sa_handle,
492                                      ipType,
493                                      &src_ip_addr,
494                                      &dst_ip_addr,
495                                      NULL,
496                                      (NETCP_CFG_ROUTE_HANDLE_T)&route,
497                                      NULL,
498                                      &error);
500     if (error == NETAPI_ERR_OK)
501     {
502             *sp_handle = globalDB.rx_sa[slot].spAppId;
503     }
504     else
505     {
506         ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
507                       "netapilib_ifAddSA: netapi_secAddRxPolicy returned error: %d.\n",
508                        error);
509         return -1;
510         }
511         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
512     "netapilib_ifAddSA: Translation of SP successful, app_id: 0x%x\n", *sp_handle);
514 #endif
515     return 0;
518 /**************************************************************************
519  * FUNCTION PURPOSE: The function is used to translate the SP configuration
520  * parameters received from the IPSec Snopper and call the NETAPI function
521  * to delete a security association
522  ********************************************************************/
523 int32_t netapilib_ifDeleteSP
525     ipsecmgr_fp_handle_t    sp_handle,
526     ipsecmgr_policy_id_t    policy_id,
527     ipsecmgr_dir_t          dir
530     /* Security Policy is deleted as part of deleting SA */
531     return 0;
532 #if 0
533     int error =0;
534     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"netapilib_ifDeleteSP: called\n");
536     if (dir == DIR_OUTBOUND)
537     {
538         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
539             "netapilib_ifDeleteSP: called for outbound SA, no RX policy to delete\n");
540             return 0;
541     }
542     netapi_secDelRxPolicy(netapi_handle,
543                           (NETCP_CFG_IPSEC_POLICY_T) sp_handle,
544                           &error);
545                           
546     return 0;
547 #endif
550 /**************************************************************************
551  * FUNCTION PURPOSE: The function is used to translate the SA configuration
552  * parameters received from the IPSec Snopper and retrieve SA context
553  * information for SA.
554  *************************************************************************/
555 int netapilib_ifGetSACtx
557     ipsecmgr_fp_handle_t    sa_handle,
558     ipsecmgr_sa_hw_ctx_t*   hw_ctx
561     uint32_t swInfo0 = 0;
562     uint32_t swInfo1 = 0;
563     nwalGlobCxtInfo_t info;
564     nwal_RetValue retVal;
566     memset(&info, 0, sizeof(nwalGlobCxtInfo_t));
567     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) netapi_handle;
568     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,"netapilib_ifGetSACtx: called\n");
571     netapip_netcpCfgGetSaInflowInfo(&netapi_get_global()->nwal_context,
572                                     (NETCP_CFG_SA_T) sa_handle,
573                                     &swInfo0,
574                                     &swInfo1);
576     hw_ctx->swinfo_sz = 2;
577     hw_ctx->swinfo[0] = swInfo0;
578     hw_ctx->swinfo[1] = swInfo1;
580  
581     if(globalDB.sa_tx_flow == -1)
582     {
583        retVal = nwal_getGlobCxtInfo(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
584                                       &info);
585         if (retVal != nwal_OK)
586         {
587             ipsecmgr_syslog_msg (SYSLOG_LEVEL_ERROR,
588                 "netapilib_ifGetSACtx: nwal_getGlobCxtInfo returned error: 0x%x\n", retVal);
589             return -1;
590         }
591         hw_ctx->flow_id = info.rxSaPaFlowId;
592         ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
593             "netapilib_ifGetSACtx: rxPaSaflowId: 0x%x, rxSaPaflowId: 0x%x\n",
594             info.rxPaSaFlowId,
595             info.rxSaPaFlowId);
596     }
597     else
598     {
599         hw_ctx->flow_id = globalDB.sa_tx_flow;
600     }
602     ipsecmgr_syslog_msg (SYSLOG_LEVEL_INFO,
603             "netapilib_ifGetSACtx: swInfo0: 0x%x, swInfo1: 0x%x, flowId: 0x%x\n",
604             hw_ctx->swinfo[0],
605             hw_ctx->swinfo[1],
606             hw_ctx->flow_id);
608    /* return success */
609     return 0;