a46d6625d7d13bd8160eb79490a6d29b737adc46
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / netapi_sec.c
1 /**************************************************************
2  * FILE PURPOSE :  NETAPI SECURITY CONFIGURATION-
3  *         user space access to security transport resources on SOC
4  **************************************************************
5  * @file netapi_sec.c
6  * 
7  * @brief DESCRIPTION:  netapi security cfg file for user space transport
8  *               library
9  * 
10  * REVISION HISTORY:
11  *
12  *  Copyright (c) Texas Instruments Incorporated 2013
13  * 
14  *  Redistribution and use in source and binary forms, with or without 
15  *  modification, are permitted provided that the following conditions 
16  *  are met:
17  *
18  *    Redistributions of source code must retain the above copyright 
19  *    notice, this list of conditions and the following disclaimer.
20  *
21  *    Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the 
23  *    documentation and/or other materials provided with the   
24  *    distribution.
25  *
26  *    Neither the name of Texas Instruments Incorporated nor the names of
27  *    its contributors may be used to endorse or promote products derived
28  *    from this software without specific prior written permission.
29  *
30  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
31  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
32  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
34  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
35  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
36  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
39  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
40  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *****************************************************************************/
43 #include "netapi_sec.h"
46 /********************************************************************
47  * FUNCTION PURPOSE:  API to add an IPSEC SA
48  ********************************************************************
49  * DESCRIPTION:  API to add an IPSEC SA
50  ********************************************************************/
51 NETCP_CFG_SA_T netapi_secAddSA(NETAPI_T h,
52                                int iface_no,
53                                NETAPI_SEC_SA_INFO_T *sa_info,
54                                nwalSecKeyParams_t * key_params,
55                                int inflow_mode,
56                                NETCP_CFG_ROUTE_HANDLE_T  route,
57                                void **p_data_mode_handle,
58                                void **p_inflow_mode_handle,
59                                void * p_user_data,
60                                int * perr)
61 {
62     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
63     nwal_RetValue       retValue;
64     NetapiNwalTransInfo_t *pTransInfo;
65     nwal_TransID_t     trans_id;
66     unsigned int appId = NETAPI_NETCP_MATCH_IPSEC | iface_no;
67     int tunnelId;
68     nwalSaIpSecId_t  saInfo;
69     int have_to_wait=1;
70     nwalTxDmPSCmdInfo_t     dmPSCmdInfo;
71     nwalSaIpSecId_t nwalSaIpSecId;
72     uint32_t    swInfo0;
73     uint32_t    swInfo1;
75     nwalCreateSAParams_t    createParam =
76     {
77         /* mac handle */
78         NULL,  //to be filled in
79         4,
80         /*nwalSaIpSecParam_t */
81             {
82                 0,/* validParams */
83                 nwal_SA_MODE_TUNNEL,  //update from input
84                 64,/* replayWindow */\
85                 NWAL_SA_DIR_INBOUND,
86                 0,
87                 0,
88                 NWAL_SA_AALG_HMAC_SHA1,/* update from input */
89                 NWAL_SA_EALG_AES_CTR,  /* update from input */
90                 { 0x00},      /* remMacAddr:  NA */
91                 12,             /* update from input, mac size */
92                 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,/* Continue parsing to next route for match */
93                 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,/* For next route fail action by default is route to host */
94                 CPPI_PARAM_NOT_SPECIFIED,         /* Use default flow configured to NWAL  if packet is routed to host */
95                 QMSS_PARAM_NOT_SPECIFIED          /* Use default queue configured to NWAL if packet is routed to host */
96            },
97            /* nwalSaIpSecKeyParams_t */
98            {0}
99     };
102     void * mac_handle = netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context,iface_no);
103     *perr =0;
104     if ((!n) || (!sa_info)  ||  (!p_data_mode_handle))
105     {
106         *perr = NETAPI_ERR_BAD_INPUT;
107         return -1;
108     }
110     /* reserve a slot */
111     tunnelId = netapip_netcpCfgFindSaSlot(&netapi_get_global()->nwal_context,
112                            iface_no);
114     if (tunnelId <0)
115     {
116         *perr= NETAPI_ERR_NOMEM;
117         return -1;
118     }
119     appId |=  (tunnelId << NETAPI_NETCP_MATCH_ID_SHIFT);
120     netapi_Log("netapi_secAddSA: app id: 0x%x\n", appId);
122     *p_data_mode_handle= NULL;  
123     *p_inflow_mode_handle= NULL;
127     if (inflow_mode & NETAPI_SEC_SA_INFLOW)
128     {
129         pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
130         if (!pTransInfo)
131         {
132             *perr =  NETAPI_ERR_BUSY;
133             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
134             return -1;
135         }
136         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
137         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
138         pTransInfo->inUse = nwal_TRUE;
139         pTransInfo->netapi_handle = h;
141         /* build SA parameters */
142         saInfo.spi = sa_info->spi;
143         memcpy(&saInfo.dst, &sa_info->dst, sizeof( nwalIpAddr_t));
144         memcpy(&saInfo.src, &sa_info->src, sizeof( nwalIpAddr_t));
145         saInfo.proto = sa_info->proto;
146         createParam.macHandle = mac_handle;
147         createParam.ipType = sa_info->ipType;
148         createParam.saIpSecParam.dir = sa_info->dir;
149         createParam.saIpSecParam.saMode = sa_info->saMode;
150         createParam.saIpSecParam.replayWindow = sa_info->replayWindow;
151         createParam.saIpSecParam.authMode = sa_info->authMode;
152         createParam.saIpSecParam.cipherMode = sa_info->cipherMode;
153         createParam.saIpSecParam.esnLo = sa_info->esnLo;
154         createParam.saIpSecParam.esnHi = sa_info->esnHi;
155         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
156             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
157             (sa_info->authMode == NWAL_SA_AALG_GMAC))
158         {
159             createParam.saIpSecParam.macSize = 16;
160         }
161         if  ((sa_info->authMode == NWAL_SA_AALG_NULL) && 
162             (!((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) || 
163                (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))))
164         {
165             createParam.saIpSecParam.replayWindow = 0;
166             createParam.saIpSecParam.macSize = 0;
167         }
168         memcpy(&createParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
170         if (route != NULL)
171         {
172             netapip_netcpCfgBuildRoute(route,&createParam.saIpSecParam.appRxPktFlowId, 
173                                          &createParam.saIpSecParam.appRxPktQueue);
174         }
176         /* fire off config message */
177         retValue = nwal_setSecAssoc (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
178                                         trans_id,
179                                         (nwal_AppId) appId,
180                                         &saInfo,
181                                         &createParam,
182                                         &pTransInfo->handle);
183         if(retValue == nwal_TRANS_COMPLETE)
184         {
185             have_to_wait=0;
186         }
187         else if(retValue !=  nwal_OK)
188         {
189             *perr = NETAPI_ERR_NWAL_ERR0;
190             netapip_freeTransInfo(pTransInfo);
191             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
192             return -1;
193         }
195         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
196         {
197             n->nwal_local.numPendingCfg++;
198             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
199                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
200             {
201                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
202             }
203             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
204             {
205                 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
206                 pTransInfo->inUse = nwal_FALSE;
207                 *perr = NETAPI_ERR_PA_FW;
208                 netapi_Log ("netapi_sec - ERROR returned by NETCP PA firmware %d\n",
209                         *perr);
210                 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
211                 return -1;
212             }
213         }
215         *p_inflow_mode_handle=pTransInfo->handle;
216         netapip_freeTransInfo(pTransInfo);
218         if (sa_info->dir == NWAL_SA_DIR_OUTBOUND)
219         {
220             memset(&nwalSaIpSecId, 0, sizeof(nwalSaIpSecId_t));
221             nwalSaIpSecId.spi = sa_info->spi;
222             memcpy(&(nwalSaIpSecId.src), &sa_info->src,sizeof( nwalIpAddr_t));
223             memcpy(&(nwalSaIpSecId.dst), &sa_info->dst,sizeof( nwalIpAddr_t));
224             nwalSaIpSecId.proto = sa_info->proto;
225             if (nwal_getSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
226                                      &nwalSaIpSecId, 
227                                      NWAL_SA_DIR_OUTBOUND,
228                                      p_inflow_mode_handle,
229                                      &swInfo0,
230                                      &swInfo1) == nwal_TRUE)
231             {
232                 //netapi_Log("netapisecAddSA swInfo0: 0x%x, swInfo1: 0x%x\n", swInfo0, swInfo1);
233             }
234             else
235                 netapi_Log("netapisecAddSA: call to nwal_getSecAssoc() returned error\n");
236         }
237     }
239     /* sideband mode */
240     if (inflow_mode &NETAPI_SEC_SA_SIDEBAND)
241     {
242         nwalCreateDmSAParams_t  dmSaParam;
243         void * dm_handle;
244         memset(&dmSaParam,0,sizeof(nwalCreateDmSAParams_t));
245         dmSaParam.dmSaParam.dmChnType= (sa_info->dir==NWAL_SA_DIR_INBOUND)?  NWAL_DM_CHAN_DECRYPT: NWAL_DM_CHAN_ENCRYPT; /**direction*/ 
246         dmSaParam.dmSaParam.replayWindow=sa_info->replayWindow;
247         dmSaParam.dmSaParam.authMode=sa_info->authMode;
248         dmSaParam.dmSaParam.cipherMode=sa_info->cipherMode;
249         dmSaParam.dmSaParam.macSize=12;
250         dmSaParam.dmSaParam.aadSize=0;
251         dmSaParam.dmSaParam.enc1st =  (sa_info->dir ==NWAL_SA_DIR_OUTBOUND) ? nwal_TRUE : nwal_FALSE;  //encypt 1st for outbound
252         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
253             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
254             (sa_info->authMode == NWAL_SA_AALG_GMAC))
255         {
256             dmSaParam.dmSaParam.macSize = 16;
257             dmSaParam.dmSaParam.aadSize=8;
258             /* Enc1st needs to always be true for combined mode algorithms */
259             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
260         }
261        else
262         {
263             dmSaParam.dmSaParam.macSize=12;
264             dmSaParam.dmSaParam.aadSize=0;
265         }
267        if  (sa_info->authMode == NWAL_SA_AALG_NULL)
268        {
269             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
270        }
271         /* todo; allow app q for Sideband return */
272         memcpy(&dmSaParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
273         retValue = nwal_setDMSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
274                                   (nwal_AppId)appId,
275                                   &dmSaParam,
276                                   &dm_handle);
277         if(retValue != nwal_OK)
278         {
279             *perr = NETAPI_ERR_NWAL_ERR0;
280             netapi_Log ("netapi_secAddSA: nwal_setDMSecAssoc() returned Error Code %d\n",
281             retValue);
282             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
283             return -1;
284         }
286         //netapi_Log("netapi_secAddSA: Creating sideband mode SA for %d ( mac %d)\n", tunnelId, iface_no); 
287         *p_data_mode_handle = dm_handle;
288         memset(&dmPSCmdInfo, 0, sizeof(nwalTxDmPSCmdInfo_t));
289         retValue =  nwal_initDMPSCmdInfo(netapip_returnNwalInstanceHandle(h),
290                                          *p_data_mode_handle,
291                                          &dmPSCmdInfo); 
292     }
294     netapip_netcpCfgInsertSa(&netapi_get_global()->nwal_context,
295                           tunnelId,
296                           (sa_info->dir ==   NWAL_SA_DIR_INBOUND) ? TRUE: FALSE,
297                           inflow_mode,
298                           &saInfo, &createParam,
299                           *p_inflow_mode_handle,
300                           *p_data_mode_handle,
301                           &dmPSCmdInfo,
302                           swInfo0,
303                           swInfo1,
304                           p_user_data);
305     return  (appId);
308 /********************************************************************
309  * FUNCTION PURPOSE:  Internal function  to dynamically switch between inflow
310  *                                  and sideband mode
311  ********************************************************************
312  * DESCRIPTION:  Internal function  to dynamically switch between inflow
313  *                                  and sideband mode
314  ********************************************************************/
315 void netapi_secInflowMode(int iface,
316                           NETCP_CFG_SA_T sa,
317                           int on)
319     /* NOT_IMPLEMENTED */
320     netapi_Log("netapi_secInflowMode:  dynamic switch between inflow and sideband is NOT_IMPLEMENTED\n");
323 /********************************************************************
324  * FUNCTION PURPOSE:  Internal function  to delete an IPSEC SA
325  ********************************************************************
326  * DESCRIPTION:  Internal function to delete an IPSEC SA
327  ********************************************************************/
328 static void netapi_secDelSA_internal(NETAPI_T h,
329                                      int iface_no,
330                                      NETCP_CFG_SA_T sa_app_id,
331                                      int flags,
332                                      int *perr)
334     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
335     nwal_RetValue       retValue;
336     NetapiNwalTransInfo_t *pTransInfo;
337     nwal_TransID_t     trans_id;
338     int tunnelId = (sa_app_id >> NETAPI_NETCP_MATCH_ID_SHIFT) &NETAPI_NETCP_MATCH_ID_MASK;
339     void * handle_inflow;
340     void * handle_sideband;
341     int have_to_wait = 1;
343     handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
344                                           tunnelId, &handle_sideband);
345     *perr =0;
347     if(handle_inflow)
348     {
349     /* get a transaction id */
350         pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
351         if (!pTransInfo)
352         {
353             *perr =  NETAPI_ERR_BUSY;
354             return;
355         }
356         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
357         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
358         pTransInfo->inUse = nwal_TRUE;
359         pTransInfo->netapi_handle = h;
361         retValue = nwal_delSecAssoc(
362                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
363                 trans_id,
364                 handle_inflow);
365         if(retValue == nwal_TRANS_COMPLETE)
366         {
367            have_to_wait=0;
368         }
369         else if(retValue !=  nwal_OK)
370         {
371                 *perr = NETAPI_ERR_NWAL_ERR0;
372                 netapi_Log ("netcp_cfg - ERROR: netapi_secDelSA_internal returned Error Code %d\n",
373                             retValue);
374                 netapip_freeTransInfo(pTransInfo);
375                 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
376         }
377         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
378         {
379             n->nwal_local.numPendingCfg++;
381             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
382                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
383             {
384                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
385             }
386             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
387             {
388                 netapip_freeTransInfo(pTransInfo);
389                 *perr = NETAPI_ERR_PA_FW;
390                  if (!flags) 
391                     netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
392                 netapi_Log ("netapi_sec - ERROR returned by NETCP PA firmware %d\n",
393                         *perr);
394                 return;
395            }
396         }
397         netapi_Log ("netapi sec: inflow tunnel %d (iface %d) deleted\n",tunnelId,iface_no);
398         netapip_freeTransInfo(pTransInfo);
399     }
400     if (handle_sideband)
401     {
402         retValue=nwal_delDMSecAssoc( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
403                                     handle_sideband);
404         if(retValue !=  nwal_OK)
405         {
406             *perr = NETAPI_ERR_NWAL_ERR0;
407              netapi_Log ("netapi_sec  - ERROR: nwal_delDMSA returned Error Code %d\n",
408                     retValue);
410         }
411         else 
412             netapi_Log("netapi_sec: Sideband SA deleted\n");
413     }
414    
415     /* zap the entry */
416     if (!flags)
417         netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
420 /********************************************************************
421  * FUNCTION PURPOSE:  API to delete an IPSEC SA
422  ********************************************************************
423  * DESCRIPTION:  API to delete an IPSEC SA
424  ********************************************************************/
425 void netapi_secDelSA(NETAPI_T h,
426                      int iface_no,
427                      NETCP_CFG_SA_T sa_app_id,
428                      int *perr)
430     netapi_secDelSA_internal( h, iface_no,  sa_app_id, 0x00, perr);
434 /********************************************************************
435  * FUNCTION PURPOSE:  API to add a recieve security policy
436  ********************************************************************
437  * DESCRIPTION:  API to add a recieve security policy
438  ********************************************************************/
439 NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h, 
440                                                NETCP_CFG_SA_T sa,
441                                                nwal_IpType ipType,
442                                                nwalIpAddr_t * src_ip_addr,
443                                                nwalIpAddr_t * dst_ip_addr,
444                                                nwalIpOpt_t * ip_qualifiers,
445                                                NETCP_CFG_ROUTE_HANDLE_T  route,
446                                                void * user_data,
447                                                int * perr)
449     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
450     nwal_RetValue       retValue;
451     NetapiNwalTransInfo_t *pTransInfo;
452     nwal_TransID_t     trans_id;
453     unsigned int appId = NETAPI_NETCP_MATCH_IPSEC_POLICY | (sa& NETAPI_NETCP_MATCH_ID_MASK);
454     int policyId;
455     int tunnelId= netapi_cfgGetMatchId(sa);
456     void * blah;
457     int iface_no = netapi_cfgGetMatchLogicalMacIface(sa);
459     nwalSecPolParams_t createParam =
460     {
461         0,  /* handle */
462         NWAL_SA_DIR_INBOUND,
463         4,      /* IP Type */
464         {0},  /* dst */
465         {0},  /* src */
466         {0 },/* IP Options */
467         NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
468         NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
469         CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
470         QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
471     };
473     void * sa_handle = NULL;
474     *perr =0;
475     
476     if ((!n) )
477     {
478         *perr = NETAPI_ERR_BAD_INPUT;
479         return -1;
480     }
482     sa_handle = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,tunnelId,&blah);
483     if (!sa_handle)
484     {
485         *perr = NETAPI_ERR_BAD_INPUT;
486         return -1;
487     }
489     /* get a transaction id */
490     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
491     if (!pTransInfo)
492     {
493         *perr =  NETAPI_ERR_BUSY;
494         return -1;
495     }
496     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
497     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
498     pTransInfo->inUse = nwal_TRUE;
499     pTransInfo->netapi_handle = h;
500     createParam.handle = sa_handle;
501     createParam.ipType = ipType;
502     if (dst_ip_addr) memcpy(&createParam.dst, dst_ip_addr, sizeof(nwalIpAddr_t)); 
503     if (src_ip_addr) memcpy(&createParam.src, src_ip_addr, sizeof(nwalIpAddr_t)); 
504     if (ip_qualifiers) memcpy(&createParam.ipOpt,ip_qualifiers ,sizeof(nwalIpOpt_t));
505     if (route != NULL)
506     {
507         netapip_netcpCfgBuildRoute(route,&createParam.appRxPktFlowId,
508                                      &createParam.appRxPktQueue);
509     }
510     /* reserve a slot */
511     policyId = netapip_netcpCfgFindPolicySlot(&netapi_get_global()->nwal_context,
512                            tunnelId);
513     if (policyId <0) 
514     {
515         *perr= NETAPI_ERR_NOMEM;
516         netapip_freeTransInfo(pTransInfo);
517         return -1;
518     }
519     appId |=  (policyId<<8);
521     /* fire off config message */
522     retValue = nwal_setSecPolicy (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
523                                   trans_id,
524                                   (nwal_AppId) appId,
525                                   &createParam,
526                                   &pTransInfo->handle);
527     if(retValue !=  nwal_OK)
528     {
529         *perr = NETAPI_ERR_NWAL_ERR0;
530         netapi_Log ("netapi sec - ERROR: nwal_setPolicy returned Error Code %d\n",
531                     retValue);
532         netapip_freeTransInfo(pTransInfo);
533         
534         netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
535         return -1;
536     }
538     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
539     {
540         n->nwal_local.numPendingCfg++;
541         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
542                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
543         {
544             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
545         }
546         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
547         {
548             netapip_freeTransInfo(pTransInfo);
549             *perr = NETAPI_ERR_PA_FW;
550             netapi_Log ("netapi_sec - ERROR2: netapi_secAddRxPolicy returned Error Code %d\n",
551                     *perr);
552             netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
553             return -1;
554         }
555     }
556     netapi_Log ("netapi sec: SA %d added to tunnel %d  mac %d\n", policyId, tunnelId, iface_no);
558     /* save stuff */
559     netapip_netcpCfgInsertPolicy(&netapi_get_global()->nwal_context,
560                            policyId,
561                           (void *) pTransInfo->handle,
562                           user_data);
563     netapip_freeTransInfo(pTransInfo);
564     return  (appId);
567 /********************************************************************
568  * FUNCTION PURPOSE:  Internal function to delete a recieve security policy
569  ********************************************************************
570  * DESCRIPTION:  Internal function to delete a recieve security policy
571  ********************************************************************/
572 static void netapi_secDelRxPolicy_internal(NETAPI_T h,
573                                            NETCP_CFG_IPSEC_POLICY_T policy_app_id,
574                                            int flags,
575                                            int *perr)
577     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
578     nwal_RetValue       retValue;
579     NetapiNwalTransInfo_t *pTransInfo;
580     nwal_TransID_t     trans_id;
581     int policyId = netapi_cfgGetMatchId(policy_app_id);
582     void * handle_policy=NULL;
584     handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,policyId);
585                                           ;
586     if (!handle_policy)
587     {
588         *perr = NETAPI_ERR_BAD_INPUT;
589         goto ERR_netapi_secDelRxPolicy_internal;
590      }
591     *perr =0;
593     /* get a transaction id */
594     pTransInfo = netapip_getFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
595     if (!pTransInfo)
596     {
597         *perr =  NETAPI_ERR_BUSY;
598         goto ERR_netapi_secDelRxPolicy_internal;
599     }
600     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
601     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
602     pTransInfo->inUse = nwal_TRUE;
603     pTransInfo->netapi_handle = h;
605     /* issue request */
606     retValue = nwal_delSecPolicy(
607                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
608                 trans_id,
609                 handle_policy);
610     if(retValue !=  nwal_OK)
611     {
612         *perr = NETAPI_ERR_NWAL_ERR0;
613         netapi_Log ("netapi sec - ERROR: netapi_secDelRxPolicy_internal returned Error Code %d\n",
614                     retValue);
615         netapip_freeTransInfo(pTransInfo);
616         goto ERR_netapi_secDelRxPolicy_internal;
617     }
619     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
620     {
621         n->nwal_local.numPendingCfg++;
622         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
623                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
624         {
625             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
626         }
627         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
628         {
629             netapip_freeTransInfo(pTransInfo);
630             *perr = NETAPI_ERR_PA_FW;
631             netapi_Log ("netapi_sec - ERROR2: netapi_secDelRxPolicy_internal returned Error Code %d\n",
632                     *perr);
633             //zap the entry
634             if (!flags)
635                 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
636             goto ERR_netapi_secDelRxPolicy_internal;
637             
638         }
639     }
640     netapi_Log ("netapi sec: policy %d (iface %d) deleted\n",policyId,(policy_app_id&0xff));
641     netapip_freeTransInfo(pTransInfo);
642     /* zap the entry */
643     if (!flags)
644     {
645         netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
646     }
647 ERR_netapi_secDelRxPolicy_internal:
648     return;
651 /********************************************************************
652  * FUNCTION PURPOSE:  API to delete a recieve security policy
653  ********************************************************************
654  * DESCRIPTION:  API to delete a recieve security policy
655  ********************************************************************/
656 void netapi_secDelRxPolicy(NETAPI_T h,
657                            NETCP_CFG_IPSEC_POLICY_T policy_app_id,
658                            int *perr)
660     netapi_secDelRxPolicy_internal(h,  policy_app_id, 0, perr);
663 /********************************************************************
664  * FUNCTION PURPOSE:  API to retrieve SA statistics via NWAL
665  ********************************************************************
666  * DESCRIPTION:  API to retrieve SA statistics via NWAL
667  ********************************************************************/
668 void  netapi_getSaStats (NETAPI_T               h, 
669                          NETCP_CFG_SA_T         handle,
670                          NETAPI_SA_STATS_T*     pSaStats)
672     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
673     void * handle_inflow;
674     void * handle_sideband;
675     int tunnelId = (handle >>8) &0xffff;
676     int have_to_wait = 1;
677     handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
678                                           tunnelId, &handle_sideband);
679     if(handle_inflow)
680     {
681         nwal_getSecAssocStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
682                                                 handle_inflow, &(pSaStats->saIpsecStats));
683         pSaStats->validParams |= NETAPI_IPSEC_STAT_VALID;
684     }
685     if(handle_sideband)
686     {
687         nwal_getDataModeStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
688                                                 handle_sideband, &(pSaStats->dataModeStats));
689         pSaStats->validParams |= NETAPI_SIDEBAND_DATA_MODE_STAT_VALID;
690     }