]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/netapi.git/blob - ti/runtime/netapi/src/netapi_sec.c
This commit adds the following:
[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:  rev 0.0.1 
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,
81         /*nwalSaIpSecParam_t */  
82             {   
83                 0,/* validParams */
84                 nwal_SA_MODE_TUNNEL,  //update from input
85                 64,/* replayWindow */
86                 NWAL_SA_DIR_INBOUND,
87                 0,
88                 0,
89                 NWAL_SA_AALG_HMAC_SHA1,                     /* update from input */
90                 NWAL_SA_EALG_AES_CTR,                       /* update from input */
91                 { 0x00},      /* remMacAddr:  NA */
92                 12,                                                         /* update from input, mac size */
93                 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
94                 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
95                 CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
96                 QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
97         },
98         /* nwalSaIpSecKeyParams_t */
99         {0}
100     };
101     void * mac_handle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context,iface_no);
102     *perr =0;
103     if ((!n) || (!sa_info)  ||  (!p_data_mode_handle) ) {*perr = NETAPI_ERR_BAD_INPUT; return -1;}
105     /* reserve a slot */
106     tunnelId = netcp_cfgp_find_sa_slot(&netapi_get_global()->nwal_context,
107                            iface_no);
109     if (tunnelId <0)
110     {
111         *perr= NETAPI_ERR_NOMEM;
112         return -1;
113     }
114     appId |=  (tunnelId<<8);
115     Debug_printf("netapi_secAddSA: app id: 0x%x\n", appId);
117     *p_data_mode_handle= NULL;  
118     *p_inflow_mode_handle= NULL;  
120     if (inflow_mode & NETAPI_SEC_SA_INFLOW)
121     {
122         pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
123         if (!pTransInfo)
124         {
125             *perr =  NETAPI_ERR_BUSY;
126             netcp_cfgp_delete_sa(&netapi_get_global()->nwal_context,tunnelId);
127             return -1;
128         }
129         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
130         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
131         pTransInfo->inUse = nwal_TRUE;
132         pTransInfo->netapi_handle = h;
134         /* build SA parameters */
135         saInfo.spi = sa_info->spi;
136         memcpy(&saInfo.dst, &sa_info->dst, sizeof( nwalIpAddr_t));
137         memcpy(&saInfo.src, &sa_info->src, sizeof( nwalIpAddr_t));
138         saInfo.proto = sa_info->proto;
139         createParam.macHandle = mac_handle;
140         createParam.ipType = sa_info->ipType;
141         createParam.saIpSecParam.dir = sa_info->dir;
142         createParam.saIpSecParam.saMode = sa_info->saMode;
143         createParam.saIpSecParam.replayWindow = sa_info->replayWindow;
144         createParam.saIpSecParam.authMode = sa_info->authMode;
145         createParam.saIpSecParam.cipherMode = sa_info->cipherMode;
146         createParam.saIpSecParam.esnLo = sa_info->esnLo;
147         createParam.saIpSecParam.esnHi = sa_info->esnHi;
148         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
149             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
150             (sa_info->authMode == NWAL_SA_AALG_GMAC))
151         {
152             createParam.saIpSecParam.macSize = 16;
153         }
154         if  ((sa_info->authMode == NWAL_SA_AALG_NULL) && 
155             (!((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) || 
156                (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))))
157         {
158             createParam.saIpSecParam.replayWindow = 0;
159             createParam.saIpSecParam.macSize = 0;
160         }
161         memcpy(&createParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
163         if (route != NULL)
164         {
165             netcp_cfgp_build_route(route,&createParam.saIpSecParam.appRxPktFlowId, 
166                                          &createParam.saIpSecParam.appRxPktQueue);
167         }
169         /* fire off config message */
170         retValue = nwal_setSecAssoc (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
171                                         trans_id,
172                                         (nwal_AppId) appId,
173                                         &saInfo,
174                                         &createParam,
175                                         &pTransInfo->handle);
176         if(retValue == nwal_TRANS_COMPLETE)
177         {
178             have_to_wait=0;
179         }
180         else if(retValue !=  nwal_OK)
181         {
182             *perr = NETAPI_ERR_NWAL_ERR0;
183             netapip_FreeTransInfo(pTransInfo);
184             netcp_cfgp_delete_sa(&netapi_get_global()->nwal_context,tunnelId);
185             return -1;
186         }
188         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
189         {
190             n->nwal_local.numPendingCfg++;
191             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
192                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
193             {
194                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
195             }
196             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
197             {
198                 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
199                 pTransInfo->inUse = nwal_FALSE;
200                 *perr = NETAPI_ERR_PA_FW;
201                 Debug_printf (">netapi_sec - ERROR returned by NETCP PA firmware %d\n",
202                         *perr);
203                 netcp_cfgp_delete_sa(&netapi_get_global()->nwal_context,tunnelId);
204                 return -1;
205             }
206         }
208         *p_inflow_mode_handle=pTransInfo->handle;
209         netapip_FreeTransInfo(pTransInfo);
211         if (sa_info->dir == NWAL_SA_DIR_OUTBOUND)
212         {
213             memset(&nwalSaIpSecId, 0, sizeof(nwalSaIpSecId_t));
214             nwalSaIpSecId.spi = sa_info->spi;
215             memcpy(&(nwalSaIpSecId.src), &sa_info->src,sizeof( nwalIpAddr_t));
216             memcpy(&(nwalSaIpSecId.dst), &sa_info->dst,sizeof( nwalIpAddr_t));
217             nwalSaIpSecId.proto = sa_info->proto;
218             if (nwal_getSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
219                                      &nwalSaIpSecId, 
220                                      NWAL_SA_DIR_OUTBOUND,
221                                      p_inflow_mode_handle,
222                                      &swInfo0,
223                                      &swInfo1) == nwal_TRUE)
224             {
225                 Debug_printf("netapisecAddSA swInfo0: 0x%x, swInfo1: 0x%x\n", swInfo0, swInfo1);
226             }
227             else
228                 Debug_printf("netapisecAddSA: call to nwal_getSecAssoc() returne error\n");
229         }
230     }
232     /* sideband mode */
233     if (inflow_mode &NETAPI_SEC_SA_SIDEBAND)
234     {
235         nwalCreateDmSAParams_t  dmSaParam;
236         void * dm_handle;
237         memset(&dmSaParam,0,sizeof(nwalCreateDmSAParams_t));
238         dmSaParam.dmSaParam.dmChnType= (sa_info->dir==NWAL_SA_DIR_INBOUND)?  NWAL_DM_CHAN_DECRYPT: NWAL_DM_CHAN_ENCRYPT; /**direction*/ 
239         dmSaParam.dmSaParam.replayWindow=sa_info->replayWindow;
240         dmSaParam.dmSaParam.authMode=sa_info->authMode;
241         dmSaParam.dmSaParam.cipherMode=sa_info->cipherMode;
242         dmSaParam.dmSaParam.macSize=12;
243         dmSaParam.dmSaParam.aadSize=0;
244         dmSaParam.dmSaParam.enc1st =  (sa_info->dir ==NWAL_SA_DIR_OUTBOUND) ? nwal_TRUE : nwal_FALSE;  //encypt 1st for outbound
245         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
246             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
247             (sa_info->authMode == NWAL_SA_AALG_GMAC))
248         {
249             dmSaParam.dmSaParam.macSize = 16;
250             dmSaParam.dmSaParam.aadSize=8;
251             /* Enc1st needs to always be true for combined mode algorithms */
252             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
253         }
254        else
255         {
256             dmSaParam.dmSaParam.macSize=12;
257             dmSaParam.dmSaParam.aadSize=0;
258         }
260        if  (sa_info->authMode == NWAL_SA_AALG_NULL)
261        {
262             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
263        }
264         /* todo; allow app q for Sideband return */
265         memcpy(&dmSaParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
266         retValue = nwal_setDMSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
267                                   (nwal_AppId)appId,
268                                   &dmSaParam,
269                                   &dm_handle);
270         if(retValue != nwal_OK)
271         {
272             *perr = NETAPI_ERR_NWAL_ERR0;
273             Debug_printf ("netapi_secAddSA: nwal_setDMSecAssoc() returned Error Code %d\n",
274             retValue);
275             netcp_cfgp_delete_sa(&netapi_get_global()->nwal_context,tunnelId);
276             return -1;
277         }
279         Debug_printf("netapi_secAddSA: Creating sideband mode SA for %d ( mac %d)\n", tunnelId, iface_no); 
280         *p_data_mode_handle = dm_handle;
281         memset(&dmPSCmdInfo, 0, sizeof(nwalTxDmPSCmdInfo_t));
282         retValue =  nwal_initDMPSCmdInfo(netapi_return_nwal_instance_handle(h),
283                                          *p_data_mode_handle,
284                                          &dmPSCmdInfo); 
285     }
287     netcp_cfgp_insert_sa(&netapi_get_global()->nwal_context,
288                           tunnelId,
289                           (sa_info->dir ==   NWAL_SA_DIR_INBOUND) ? TRUE: FALSE,
290                           inflow_mode,
291                           &saInfo, &createParam,
292                           *p_inflow_mode_handle,
293                           *p_data_mode_handle,
294                           &dmPSCmdInfo,
295                           swInfo0,
296                           swInfo1,
297                           p_user_data);
298     return  (appId);
301 /********************************************************************
302  * FUNCTION PURPOSE:  Internal function  to dynamically switch between inflow
303  *                                  and sideband mode
304  ********************************************************************
305  * DESCRIPTION:  Internal function  to dynamically switch between inflow
306  *                                  and sideband mode
307  ********************************************************************/
308 void netapi_secInflowMode(int iface, NETCP_CFG_SA_T sa,  int on)
310     /* NOT_IMPLEMENTED */
311     Debug_printf("netapi_secInflowMode:  dynamic switch between inflow and sideband is NOT_IMPLEMENTED\n");
314 /********************************************************************
315  * FUNCTION PURPOSE:  Internal function  to delete an IPSEC SA
316  ********************************************************************
317  * DESCRIPTION:  Internal function to delete an IPSEC SA
318  ********************************************************************/
319 static void netapi_secDelSA_internal(NETAPI_T h,int iface_no, NETCP_CFG_SA_T  sa_app_id, int flags, int *perr)
321     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
322     nwal_RetValue       retValue;
323     NetapiNwalTransInfo_t *pTransInfo;
324     nwal_TransID_t     trans_id;
325     int tunnelId = (sa_app_id >>8) &0xffff;
326     void * handle_inflow;
327     void * handle_sideband;
328     int have_to_wait = 1;
330     handle_inflow = netcp_cfgp_get_sa_handles(&netapi_get_global()->nwal_context,
331                                           tunnelId, &handle_sideband);
332     *perr =0;
334     if(handle_inflow)
335     {
336     /* get a transaction id */
337         pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
338         if (!pTransInfo)
339         {
340             *perr =  NETAPI_ERR_BUSY;
341             return;
342         }
343         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
344         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
345         pTransInfo->inUse = nwal_TRUE;
346         pTransInfo->netapi_handle = h;
348         retValue = nwal_delSecAssoc(
349                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
350                 trans_id,
351                 handle_inflow);
352         if(retValue == nwal_TRANS_COMPLETE)
353         {
354            have_to_wait=0;
355         }
356         else if(retValue !=  nwal_OK)
357         {
358                 *perr = NETAPI_ERR_NWAL_ERR0;
359                 Debug_printf (">netcp cfg - ERROR: netapi_secDelSA_internal returned Error Code %d\n",
360                             retValue);
361                 netapip_FreeTransInfo(pTransInfo);
362                 netcp_cfgp_delete_sa(&netapi_get_global()->nwal_context,tunnelId);
363         }
364         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
365         {
366             n->nwal_local.numPendingCfg++;
368             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
369                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
370             {
371                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
372             }
373             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
374             {
375                 netapip_FreeTransInfo(pTransInfo);
376                 *perr = NETAPI_ERR_PA_FW;
377                  if (!flags) 
378                     netcp_cfgp_delete_sa(&netapi_get_global()->nwal_context, tunnelId);
379                 Debug_printf (">netapi_sec - ERROR returned by NETCP PA firmware %d\n",
380                         *perr);
381                 return;
382            }
383         }
384         Debug_printf (">netapi sec: inflow tunnel %d (iface %d) deleted\n",tunnelId,iface_no);
385         netapip_FreeTransInfo(pTransInfo);
386     }
387     if (handle_sideband)
388     {
389         retValue=nwal_delDMSecAssoc( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
390                                     handle_sideband);
391         if(retValue !=  nwal_OK)
392         {
393             *perr = NETAPI_ERR_NWAL_ERR0;
394              Debug_printf (">netapi_sec  - ERROR: nwal_delDMSA returned Error Code %d\n",
395                     retValue);
397         }
398         else 
399             Debug_printf(">netapi_sec: Sideband SA deleted\n");
400     }
401    
402     /* zap the entry */
403     if (!flags)
404         netcp_cfgp_delete_sa(&netapi_get_global()->nwal_context, tunnelId);
407 /********************************************************************
408  * FUNCTION PURPOSE:  API to delete an IPSEC SA
409  ********************************************************************
410  * DESCRIPTION:  API to delete an IPSEC SA
411  ********************************************************************/
412 void netapi_secDelSA(NETAPI_T h,int iface_no, NETCP_CFG_SA_T  sa_app_id,  int *perr)
414     netapi_secDelSA_internal( h, iface_no,  sa_app_id, 0x00, perr);
418 /********************************************************************
419  * FUNCTION PURPOSE:  API to add a recieve security policy
420  ********************************************************************
421  * DESCRIPTION:  API to add a recieve security policy
422  ********************************************************************/
423 NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h, //the  netapi handle
424                                 NETCP_CFG_SA_T sa,  //tunnel to attach to
425                                 nwal_IpType ipType,     //V4 or V6
426                                 nwalIpAddr_t  * src_ip_addr,  //src (from where)
427                                 nwalIpAddr_t  * dst_ip_addr,  //dst (us)
428                                 nwalIpOpt_t * ip_qualifiers,  //other qualifiers
429                                 NETCP_CFG_ROUTE_HANDLE_T  route,  //Optional route
430                                 void * user_data, // optional user specified data associated with policy
431                                 int * perr)
433     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
434     nwal_RetValue       retValue;
435     NetapiNwalTransInfo_t *pTransInfo;
436     nwal_TransID_t     trans_id;
437     unsigned int appId = NETAPI_NETCP_MATCH_IPSEC_POLICY | (sa&0xff);
438     int policyId;
439     int tunnelId= (sa>>8)&0xff;
440     void * blah;
441     int iface_no = sa&0xff;
442     nwalSecPolParams_t createParam =
443     {
444         0,  /* handle */
445         NWAL_SA_DIR_INBOUND,
446         4,      /* IP Type */
447         {0},  /* dst */
448         {0},  /* src */
449         {0 },/* IP Options */
450         NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
451         NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
452         CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
453         QMSS_PARAM_NOT_SPECIFIED                     /* Use default queue configured to NWAL if packet is routed to host */
454     };
456     void * sa_handle = NULL;
457     *perr =0;
458     
459     if ((!n) )
460     {
461         *perr = NETAPI_ERR_BAD_INPUT;
462         return -1;
463     }
465     sa_handle = netcp_cfgp_get_sa_handles(&netapi_get_global()->nwal_context,tunnelId,&blah);
466     if (!sa_handle)
467     {
468         *perr = NETAPI_ERR_BAD_INPUT;
469         return -1;
470     }
472     /* get a transaction id */
473     pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
474     if (!pTransInfo)
475     {
476         *perr =  NETAPI_ERR_BUSY;
477         return -1;
478     }
479     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
480     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
481     pTransInfo->inUse = nwal_TRUE;
482     pTransInfo->netapi_handle = h;
483     createParam.handle = sa_handle;
484     createParam.ipType = ipType;
485     if (dst_ip_addr) memcpy(&createParam.dst, dst_ip_addr, sizeof(nwalIpAddr_t)); 
486     if (src_ip_addr) memcpy(&createParam.src, src_ip_addr, sizeof(nwalIpAddr_t)); 
487     if (ip_qualifiers) memcpy(&createParam.ipOpt,ip_qualifiers ,sizeof(nwalIpOpt_t));
488     if (route != NULL)
489     {
490         netcp_cfgp_build_route(route,&createParam.appRxPktFlowId,
491                                      &createParam.appRxPktQueue);
492     }
493     /* reserve a slot */
494     policyId = netcp_cfgp_find_policy_slot(&netapi_get_global()->nwal_context,
495                            tunnelId);
496     if (policyId <0) 
497     {
498         *perr= NETAPI_ERR_NOMEM;
499         netapip_FreeTransInfo(pTransInfo);
500         return -1;
501     }
502     appId |=  (policyId<<8);
504     /* fire off config message */
505     retValue = nwal_setSecPolicy (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
506                                   trans_id,
507                                   (nwal_AppId) appId,
508                                   &createParam,
509                                   &pTransInfo->handle);
510     if(retValue !=  nwal_OK)
511     {
512         *perr = NETAPI_ERR_NWAL_ERR0;
513         Debug_printf (">netapi sec - ERROR: nwal_setPolicy returned Error Code %d\n",
514                     retValue);
515         netapip_FreeTransInfo(pTransInfo);
516         
517         netcp_cfgp_delete_policy(&netapi_get_global()->nwal_context,policyId);
518         return -1;
519     }
521     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
522     {
523         n->nwal_local.numPendingCfg++;
524         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
525                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
526         {
527             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
528         }
529         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
530         {
531             netapip_FreeTransInfo(pTransInfo);
532             *perr = NETAPI_ERR_PA_FW;
533             Debug_printf (">netapi_sec - ERROR2: netapi_secAddRxPolicy returned Error Code %d\n",
534                     *perr);
535             netcp_cfgp_delete_policy(&netapi_get_global()->nwal_context,policyId);
536             return -1;
537         }
538     }
539     Debug_printf (">netapi sec: SA %d added to tunnel %d  mac %d\n", policyId, tunnelId, iface_no);
541     /* save stuff */
542     netcp_cfgp_insert_policy(&netapi_get_global()->nwal_context,
543                            policyId,
544                           (void *) pTransInfo->handle,
545                           user_data);
546     netapip_FreeTransInfo(pTransInfo);
547     return  (appId);
550 /********************************************************************
551  * FUNCTION PURPOSE:  Internal function to delete a recieve security policy
552  ********************************************************************
553  * DESCRIPTION:  Internal function to delete a recieve security policy
554  ********************************************************************/
555 static void netapi_secDelRxPolicy_internal(NETAPI_T h, NETCP_CFG_IPSEC_POLICY_T policy_app_id, int flags, int *perr)
557     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
558     nwal_RetValue       retValue;
559     NetapiNwalTransInfo_t *pTransInfo;
560     nwal_TransID_t     trans_id;
561     int policyId = (policy_app_id >>8) &0xffff;
562     void * handle_policy=NULL;
564     handle_policy = netcp_cfgp_get_policy(&netapi_get_global()->nwal_context,policyId);
565                                           ;
566     if (!handle_policy)
567     {
568         *perr = NETAPI_ERR_BAD_INPUT;
569         goto ERR_netapi_secDelRxPolicy_internal;
570      }
571     *perr =0;
573     /* get a transaction id */
574     pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
575     if (!pTransInfo)
576     {
577         *perr =  NETAPI_ERR_BUSY;
578         goto ERR_netapi_secDelRxPolicy_internal;
579     }
580     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
581     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
582     pTransInfo->inUse = nwal_TRUE;
583     pTransInfo->netapi_handle = h;
585     /* issue request */
586     retValue = nwal_delSecPolicy(
587                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
588                 trans_id,
589                 handle_policy);
590     if(retValue !=  nwal_OK)
591     {
592         *perr = NETAPI_ERR_NWAL_ERR0;
593         Debug_printf (">netapi sec - ERROR: netapi_secDelRxPolicy_internal returned Error Code %d\n",
594                     retValue);
595         netapip_FreeTransInfo(pTransInfo);
596         goto ERR_netapi_secDelRxPolicy_internal;
597     }
599     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
600     {
601         n->nwal_local.numPendingCfg++;
602         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
603                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
604         {
605             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
606         }
607         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
608         {
609             netapip_FreeTransInfo(pTransInfo);
610             *perr = NETAPI_ERR_PA_FW;
611             Debug_printf (">netapi_sec - ERROR2: netapi_secDelRxPolicy_internal returned Error Code %d\n",
612                     *perr);
613             //zap the entry
614             if (!flags)
615                 netcp_cfgp_delete_policy(&netapi_get_global()->nwal_context, policyId);
616             goto ERR_netapi_secDelRxPolicy_internal;
617             
618         }
619     }
620     Debug_printf (">netapi sec: policy %d (iface %d) deleted\n",policyId,(policy_app_id&0xff));
621     netapip_FreeTransInfo(pTransInfo);
622     /* zap the entry */
623     if (!flags)
624     {
625         netcp_cfgp_delete_policy(&netapi_get_global()->nwal_context, policyId);
626     }
627 ERR_netapi_secDelRxPolicy_internal:
628     return;
631 /********************************************************************
632  * FUNCTION PURPOSE:  API to delete a recieve security policy
633  ********************************************************************
634  * DESCRIPTION:  API to delete a recieve security policy
635  ********************************************************************/
636 void netapi_secDelRxPolicy(NETAPI_T h, NETCP_CFG_IPSEC_POLICY_T policy_app_id, int *perr)
638     netapi_secDelRxPolicy_internal(h,  policy_app_id, 0, perr);
641 /********************************************************************
642  * FUNCTION PURPOSE:  API to retrieve SA statistics via NWAL
643  ********************************************************************
644  * DESCRIPTION:  API to retrieve SA statistics via NWAL
645  ********************************************************************/
646 void  netapi_getSaStats (NETAPI_T               h, 
647                          NETCP_CFG_SA_T         handle,
648                          NETAPI_SA_STATS_T*     pSaStats)
651     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
652     void * handle_inflow;
653     void * handle_sideband;
654     int tunnelId = (handle >>8) &0xffff;
655     int have_to_wait = 1;
656     handle_inflow = netcp_cfgp_get_sa_handles(&netapi_get_global()->nwal_context,
657                                           tunnelId, &handle_sideband);
658     if(handle_inflow)
659     {
660         nwal_getSecAssocStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
661                                                 handle_inflow, &(pSaStats->saIpsecStats));
662         pSaStats->validParams |= NETAPI_IPSEC_STAT_VALID;
663     }
664     if(handle_sideband)
665     {
666         nwal_getDataModeStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
667                                                 handle_sideband, &(pSaStats->dataModeStats));
668         pSaStats->validParams |= NETAPI_SIDEBAND_DATA_MODE_STAT_VALID;
669     }
670