]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/netapi.git/blob - ti/runtime/netapi/src/netapi_sec.c
9c6c6a2d00fc627fdbc55b3cde1e09041f48a66b
[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.h"
45 NETAPI_SA_INFO_LOCAL_T netapi_sa_db[TUNE_NETAPI_MAX_SA];
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 = 0;
73     uint32_t    swInfo1 = 0;
74     int sa_db_slot;
75     int free_sa_db_slot = 0;
76     nwalCreateSAParams_t    createParam =
77     {
78         /* mac handle */
79         NULL,  //to be filled in
80         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                 0                                 /* route type */
98            },
99            /* nwalSaIpSecKeyParams_t */
100            {0}
101     };
104     void * mac_handle = netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context,iface_no);
105     *perr =NETAPI_ERR_OK;
106     if ((!n) || (!sa_info)  ||  (!p_data_mode_handle))
107     {
108         *perr = NETAPI_ERR_BAD_INPUT;
109         return -1;
110     }
112     /* prior to building table, will need to store SA entry in local database,
113      * and make sure this SA has not been already offloaded, if already off-loaded,
114      * just return app_id associated with the SA */
116     for(sa_db_slot=0; sa_db_slot < TUNE_NETAPI_MAX_SA; sa_db_slot++)
117     {
118         if (netapi_sa_db[sa_db_slot].inUse)
119         {
120             if (sa_info->ipType == nwal_IPV4)
121             {
122                 if (netapi_sa_db[sa_db_slot].spi != sa_info->spi)
123                     continue;
124                 if(memcmp(&netapi_sa_db[sa_db_slot].dst.ipv4,
125                           &sa_info->dst.ipv4, sizeof(sa_info->dst.ipv4)))
126                     continue;
128                 netapi_sa_db[sa_db_slot].ref_count++;
129                 return netapi_sa_db[sa_db_slot].app_id;
130             }
131             else if (sa_info->ipType == nwal_IPV6)
132             {
133                 if (netapi_sa_db[sa_db_slot].spi != sa_info->spi)
134                     continue;
135                 if(memcmp(&netapi_sa_db[sa_db_slot].dst.ipv6,
136                           &sa_info->dst.ipv6, sizeof(sa_info->dst.ipv6)))
137                     continue;
139                 netapi_sa_db[sa_db_slot].ref_count++;
140                 return netapi_sa_db[sa_db_slot].app_id;
141             }
142             else
143             {
144                 *perr = NETAPI_ERR_BAD_INPUT;
145                 return -1;
146             }
147         }
148         else
149         {
150             /* found free slot */
151             free_sa_db_slot = sa_db_slot;
152         }
153     }
154     saInfo.spi = sa_info->spi;
156     memcpy(&saInfo.dst, &sa_info->dst, sizeof( nwalIpAddr_t));
157     
158     /* reserve a slot */
159     tunnelId = netapip_netcpCfgFindSaSlot(n,
160                                           &netapi_get_global()->nwal_context,
161                                           iface_no);
163     if (tunnelId <0)
164     {
165         *perr= NETAPI_ERR_NOMEM;
166         return -1;
167     }
168     appId |=  (tunnelId << NETAPI_NETCP_MATCH_ID_SHIFT);
170     *p_data_mode_handle= NULL;  
171     *p_inflow_mode_handle= NULL;
175     if (inflow_mode & NETAPI_SEC_SA_INFLOW)
176     {
177         pTransInfo = netapip_getFreeTransInfo(n,
178                                               (NETAPI_PROC_GLOBAL_T *) n->proc_global,
179                                                &trans_id);
180         if (!pTransInfo)
181         {
182             *perr =  NETAPI_ERR_BUSY;
183             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
184             return -1;
185         }
186         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
187         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
188         pTransInfo->inUse = nwal_TRUE;
189         pTransInfo->netapi_handle = h;
191         /* build SA parameters */
192         saInfo.spi = sa_info->spi;
193         memcpy(&saInfo.dst, &sa_info->dst, sizeof( nwalIpAddr_t));
194         memcpy(&saInfo.src, &sa_info->src, sizeof( nwalIpAddr_t));
195         saInfo.proto = sa_info->proto;
196         createParam.macHandle = mac_handle;
197         createParam.ipType = sa_info->ipType;
198         createParam.saIpSecParam.dir = sa_info->dir;
199         createParam.saIpSecParam.saMode = sa_info->saMode;
200         createParam.saIpSecParam.replayWindow = sa_info->replayWindow;
201         createParam.saIpSecParam.authMode = sa_info->authMode;
202         createParam.saIpSecParam.cipherMode = sa_info->cipherMode;
203         createParam.saIpSecParam.esnLo = sa_info->esnLo;
204         createParam.saIpSecParam.esnHi = sa_info->esnHi;
205         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
206             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
207             (sa_info->authMode == NWAL_SA_AALG_GMAC)      ||
208             (sa_info->authMode == NWAL_SA_AALG_HMAC_SHA2_256)      ||
209             (sa_info->authMode == NWAL_SA_AALG_HMAC_SHA2_256_RFC4868))
210         {
211             createParam.saIpSecParam.macSize = 16;
212         }
213         if  ((sa_info->authMode == NWAL_SA_AALG_NULL) && 
214             (!((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) || 
215                (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))))
216         {
217             createParam.saIpSecParam.replayWindow = 0;
218             createParam.saIpSecParam.macSize = 0;
219         }
220         memcpy(&createParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
222         if (route != NULL)
223         {
224             if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
225                 NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
226             {
227                createParam.saIpSecParam.validParams |= 
228                         NWAL_SA_INFO_VALID_PARAM_ROUTE_TYPE;
229             }
230             netapip_netcpCfgBuildRoute(route,
231                                        &createParam.saIpSecParam.appRxPktFlowId,
232                                        &createParam.saIpSecParam.appRxPktQueue,
233                                        &createParam.saIpSecParam.routeType);
234         }
236         /* fire off config message */
237         retValue = nwal_setSecAssoc (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
238                                         trans_id,
239                                         (nwal_AppId) appId,
240                                         &saInfo,
241                                         &createParam,
242                                         &pTransInfo->handle);
243         if(retValue == nwal_TRANS_COMPLETE)
244         {
245             have_to_wait=0;
246         }
247         else if(retValue !=  nwal_OK)
248         {
249             *perr = NETAPI_ERR_NWAL_ERR0;
250             netapip_freeTransInfo(pTransInfo);
251             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
252             return -1;
253         }
255         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
256         {
257             n->nwal_local.numPendingCfg++;
258             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
259                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
260             {
261                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
262             }
263             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
264             {
265                 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
266                 pTransInfo->inUse = nwal_FALSE;
267                 *perr = NETAPI_ERR_PA_FW;
268                 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
269                 return -1;
270             }
271         }
273         *p_inflow_mode_handle=pTransInfo->handle;
274         netapip_freeTransInfo(pTransInfo);
276         if (sa_info->dir == NWAL_SA_DIR_OUTBOUND)
277         {
278             memset(&nwalSaIpSecId, 0, sizeof(nwalSaIpSecId_t));
279             nwalSaIpSecId.spi = sa_info->spi;
280             memcpy(&(nwalSaIpSecId.src), &sa_info->src,sizeof( nwalIpAddr_t));
281             memcpy(&(nwalSaIpSecId.dst), &sa_info->dst,sizeof( nwalIpAddr_t));
282             nwalSaIpSecId.proto = sa_info->proto;
283             if (nwal_getSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
284                                      &nwalSaIpSecId, 
285                                      NWAL_SA_DIR_OUTBOUND,
286                                      p_inflow_mode_handle,
287                                      &swInfo0,
288                                      &swInfo1) != nwal_TRUE)
289                 netapi_Log("netapisecAddSA: call to nwal_getSecAssoc() returned error\n");
290         }
291     }
293     /* sideband mode */
294     if (inflow_mode &NETAPI_SEC_SA_SIDEBAND)
295     {
296         nwalCreateDmSAParams_t  dmSaParam;
297         void * dm_handle;
298         memset(&dmSaParam,0,sizeof(nwalCreateDmSAParams_t));
299         dmSaParam.dmSaParam.dmChnType= (sa_info->dir==NWAL_SA_DIR_INBOUND)?  NWAL_DM_CHAN_DECRYPT: NWAL_DM_CHAN_ENCRYPT; /**direction*/ 
300         dmSaParam.dmSaParam.replayWindow=sa_info->replayWindow;
301         dmSaParam.dmSaParam.authMode=sa_info->authMode;
302         dmSaParam.dmSaParam.cipherMode=sa_info->cipherMode;
303         dmSaParam.dmSaParam.macSize=12;
304         dmSaParam.dmSaParam.aadSize=0;
305         dmSaParam.dmSaParam.enc1st =  (sa_info->dir ==NWAL_SA_DIR_OUTBOUND) ? nwal_TRUE : nwal_FALSE;  //encypt 1st for outbound
306         if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
307             (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
308             (sa_info->authMode == NWAL_SA_AALG_GMAC))
309         {
310             dmSaParam.dmSaParam.macSize = 16;
311             dmSaParam.dmSaParam.aadSize=8;
312             /* Enc1st needs to always be true for combined mode algorithms */
313             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
314         }
315        else
316         {
317             dmSaParam.dmSaParam.macSize=12;
318             dmSaParam.dmSaParam.aadSize=0;
319         }
321        if  (sa_info->authMode == NWAL_SA_AALG_NULL)
322        {
323             dmSaParam.dmSaParam.enc1st = nwal_TRUE;
324        }
325         /* todo; allow app q for Sideband return */
326         memcpy(&dmSaParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
327         retValue = nwal_setDMSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
328                                   (nwal_AppId)appId,
329                                   &dmSaParam,
330                                   &dm_handle);
331         if(retValue != nwal_OK)
332         {
333             *perr = NETAPI_ERR_NWAL_ERR0;
334             netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
335             return -1;
336         }
338         *p_data_mode_handle = dm_handle;
339         memset(&dmPSCmdInfo, 0, sizeof(nwalTxDmPSCmdInfo_t));
340         retValue =  nwal_initDMPSCmdInfo(netapip_returnNwalInstanceHandle(h),
341                                          *p_data_mode_handle,
342                                          &dmPSCmdInfo); 
343     }
345     netapip_netcpCfgInsertSa(&netapi_get_global()->nwal_context,
346                           tunnelId,
347                           (sa_info->dir ==   NWAL_SA_DIR_INBOUND) ? NETAPI_TRUE: NETAPI_FALSE,
348                           inflow_mode,
349                           &saInfo,
350                           &createParam,
351                           *p_inflow_mode_handle,
352                           *p_data_mode_handle,
353                           &dmPSCmdInfo,
354                           swInfo0,
355                           swInfo1,
356                           p_user_data);
357     netapi_sa_db[free_sa_db_slot].app_id = appId;
358     netapi_sa_db[free_sa_db_slot].inUse = 1;
359     netapi_sa_db[free_sa_db_slot].spi = sa_info->spi;
360     netapi_sa_db[free_sa_db_slot].ref_count++;
361     memcpy(&(netapi_sa_db[free_sa_db_slot].dst), &sa_info->dst,sizeof( nwalIpAddr_t));
362     return  (appId);
365 /********************************************************************
366  * FUNCTION PURPOSE:  Internal function  to dynamically switch between inflow
367  *                                  and sideband mode
368  ********************************************************************
369  * DESCRIPTION:  Internal function  to dynamically switch between inflow
370  *                                  and sideband mode
371  ********************************************************************/
372 void netapi_secInflowMode(int iface,
373                           NETCP_CFG_SA_T sa,
374                           int on)
376     /* NOT_IMPLEMENTED */
379 /********************************************************************
380  * FUNCTION PURPOSE:  Internal function  to delete an IPSEC SA
381  ********************************************************************
382  * DESCRIPTION:  Internal function to delete an IPSEC SA
383  ********************************************************************/
384 static void netapi_secDelSA_internal(NETAPI_T h,
385                                      int iface_no,
386                                      NETCP_CFG_SA_T sa_app_id,
387                                      int flags,
388                                      int *perr)
390     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
391     nwal_RetValue       retValue;
392     NetapiNwalTransInfo_t *pTransInfo;
393     nwal_TransID_t     trans_id;
394     int tunnelId = (sa_app_id >> NETAPI_NETCP_MATCH_ID_SHIFT) &NETAPI_NETCP_MATCH_ID_MASK;
395     void * handle_inflow;
396     void * handle_sideband;
397     int have_to_wait = 1;
398     int sa_db_slot;
400     *perr =0;
401     for(sa_db_slot=0; sa_db_slot < TUNE_NETAPI_MAX_SA; sa_db_slot++)
402     {
403             if((netapi_sa_db[sa_db_slot].inUse) &&
404             (netapi_sa_db[sa_db_slot].app_id == sa_app_id))
405             {
406                 if(!netapi_sa_db[sa_db_slot].ref_count)
407                 {
408                     *perr = NETAPI_ERR_NOTFOUND;
409                     return;
410                 }
411                 netapi_sa_db[sa_db_slot].ref_count--;
412                 if(netapi_sa_db[sa_db_slot].ref_count)
413                 {
414                     return;
415                 }
416                 else
417                 {
418                     netapi_sa_db[sa_db_slot].inUse = 0;
419                     break;
420                 }
421             }
422     }
423     handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
424                                           tunnelId, &handle_sideband);
427     if(handle_inflow)
428     {
429     /* get a transaction id */
430         pTransInfo = netapip_getFreeTransInfo(n,
431                                               (NETAPI_PROC_GLOBAL_T *) n->proc_global,
432                                               &trans_id);
433         if (!pTransInfo)
434         {
435             *perr =  NETAPI_ERR_BUSY;
436             return;
437         }
438         pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
439         pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
440         pTransInfo->inUse = nwal_TRUE;
441         pTransInfo->netapi_handle = h;
443         retValue = nwal_delSecAssoc(
444                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
445                 trans_id,
446                 handle_inflow);
447         if(retValue == nwal_TRANS_COMPLETE)
448         {
449            have_to_wait=0;
450         }
451         else if(retValue !=  nwal_OK)
452         {
453                 *perr = NETAPI_ERR_NWAL_ERR0;
454                 netapip_freeTransInfo(pTransInfo);
455                 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
456         }
457         if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
458         {
459             n->nwal_local.numPendingCfg++;
461             while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
462                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
463             {
464                 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
465             }
466             if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
467             {
468                 netapip_freeTransInfo(pTransInfo);
469                 *perr = NETAPI_ERR_PA_FW;
470                  if (!flags) 
471                     netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
472                 return;
473            }
474         }
475         netapip_freeTransInfo(pTransInfo);
476     }
477     if (handle_sideband)
478     {
479         retValue=nwal_delDMSecAssoc( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
480                                     handle_sideband);
481         if(retValue !=  nwal_OK)
482         {
483             *perr = NETAPI_ERR_NWAL_ERR0;
484         }
485     }
487     /* zap the entry */
488     if (!flags)
489         netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
492 /********************************************************************
493  * FUNCTION PURPOSE:  API to delete an IPSEC SA
494  ********************************************************************
495  * DESCRIPTION:  API to delete an IPSEC SA
496  ********************************************************************/
497 void netapi_secDelSA(NETAPI_T h,
498                      int iface_no,
499                      NETCP_CFG_SA_T sa_app_id,
500                      int *perr)
502     netapi_secDelSA_internal( h, iface_no,  sa_app_id, 0x00, perr);
506 /********************************************************************
507  * FUNCTION PURPOSE:  API to add a receive security policy
508  ********************************************************************
509  * DESCRIPTION:  API to add a receive security policy
510  ********************************************************************/
511 NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h, 
512                                                NETCP_CFG_SA_T sa,
513                                                nwal_IpType ipType,
514                                                nwalIpAddr_t * src_ip_addr,
515                                                nwalIpAddr_t * dst_ip_addr,
516                                                nwalIpOpt_t * ip_qualifiers,
517                                                NETCP_CFG_ROUTE_HANDLE_T  route,
518                                                void * user_data,
519                                                int * perr)
521     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
522     nwal_RetValue       retValue;
523     NetapiNwalTransInfo_t *pTransInfo;
524     nwal_TransID_t     trans_id;
525     unsigned int appId = NETAPI_NETCP_MATCH_IPSEC_POLICY;
526     int policyId;
527     int tunnelId= netapi_cfgGetMatchId(sa);
528     void * blah;
529     int iface_no = netapi_cfgGetMatchLogicalMacIface(sa);
531     nwalSecPolParams_t createParam =
532     {
533         0,  /* handle */
534         0,  /* valid params */
535         NWAL_SA_DIR_INBOUND,
536         4,      /* IP Type */
537         {0},  /* dst */
538         {0},  /* src */
539         {0 },/* IP Options */
540         NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,       /* Continue parsing to next route for match */
541         NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,            /* For next route fail action by default is route to host */
542         CPPI_PARAM_NOT_SPECIFIED,                    /* Use default flow configured to NWAL  if packet is routed to host */
543         QMSS_PARAM_NOT_SPECIFIED,                    /* Use default queue configured to NWAL if packet is routed to host */
544         0                                            /* Optional: route type */
545     };
547     void * sa_handle = NULL;
548     *perr =0;
549     
550     if ((!n) )
551     {
552         *perr = NETAPI_ERR_BAD_INPUT;
553         return -1;
554     }
556     sa_handle = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,tunnelId,&blah);
557     if (!sa_handle)
558     {
559         *perr = NETAPI_ERR_BAD_INPUT;
560         return -1;
561     }
563     /* get a transaction id */
564     pTransInfo = netapip_getFreeTransInfo(n,
565                                           (NETAPI_PROC_GLOBAL_T *) n->proc_global,
566                                           &trans_id);
567     if (!pTransInfo)
568     {
569         *perr =  NETAPI_ERR_BUSY;
570         return -1;
571     }
572     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
573     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
574     pTransInfo->inUse = nwal_TRUE;
575     pTransInfo->netapi_handle = h;
576     createParam.handle = sa_handle;
577     createParam.ipType = ipType;
578     if (dst_ip_addr) memcpy(&createParam.dst, dst_ip_addr, sizeof(nwalIpAddr_t)); 
579     if (src_ip_addr) memcpy(&createParam.src, src_ip_addr, sizeof(nwalIpAddr_t)); 
580     if (ip_qualifiers) memcpy(&createParam.ipOpt,ip_qualifiers ,sizeof(nwalIpOpt_t));
581     if (route != NULL)
582     {
583         if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
584             NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
585         {
586            createParam.validParams |= 
587                     NWAL_SET_SEC_POLICY_VALID_PARAM_ROUTE_TYPE;
588         }
589         netapip_netcpCfgBuildRoute(route,
590                                    &createParam.appRxPktFlowId,
591                                    &createParam.appRxPktQueue,
592                                    &createParam.routeType);
593     }
594     /* reserve a slot */
595     policyId = netapip_netcpCfgFindPolicySlot(n,
596                                               &netapi_get_global()->nwal_context,
597                                               tunnelId);
598     if (policyId <0) 
599     {
600         *perr= NETAPI_ERR_NOMEM;
601         netapip_freeTransInfo(pTransInfo);
602         return -1;
603     }
604     appId |=  (policyId <<8);
606     /* fire off config message */
607     retValue = nwal_setSecPolicy (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
608                                   trans_id,
609                                   (nwal_AppId) appId,
610                                   &createParam,
611                                   &pTransInfo->handle);
612     if(retValue !=  nwal_OK)
613     {
614         *perr = NETAPI_ERR_NWAL_ERR0;
615         netapip_freeTransInfo(pTransInfo);
616         
617         netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
618         return -1;
619     }
621     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
622     {
623         n->nwal_local.numPendingCfg++;
624         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
625                 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
626         {
627             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
628         }
629         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
630         {
631             netapip_freeTransInfo(pTransInfo);
632             *perr = NETAPI_ERR_PA_FW;
633             netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
634             return -1;
635         }
636     }
638     /* save stuff */
639     netapip_netcpCfgInsertPolicy(&netapi_get_global()->nwal_context,
640                            policyId,
641                           (void *) pTransInfo->handle,
642                           user_data);
643     netapip_freeTransInfo(pTransInfo);
644     return  (appId);
647 /********************************************************************
648  * FUNCTION PURPOSE:  Internal function to delete a receive security policy
649  ********************************************************************
650  * DESCRIPTION:  Internal function to delete a receive security policy
651  ********************************************************************/
652 static void netapi_secDelRxPolicy_internal(NETAPI_T h,
653                                            NETCP_CFG_IPSEC_POLICY_T policy_app_id,
654                                            int flags,
655                                            int *perr)
657     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
658     nwal_RetValue       retValue;
659     NetapiNwalTransInfo_t *pTransInfo;
660     nwal_TransID_t     trans_id;
661     int policyId = netapi_cfgGetMatchId(policy_app_id);
662     void * handle_policy=NULL;
664     handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,policyId);
665                                           ;
666     if (!handle_policy)
667     {
668         *perr = NETAPI_ERR_BAD_INPUT;
669         goto ERR_netapi_secDelRxPolicy_internal;
670      }
671     *perr =0;
673     /* get a transaction id */
674     pTransInfo = netapip_getFreeTransInfo(n,
675                                          (NETAPI_PROC_GLOBAL_T *) n->proc_global,
676                                          &trans_id);
677     if (!pTransInfo)
678     {
679         *perr =  NETAPI_ERR_BUSY;
680         goto ERR_netapi_secDelRxPolicy_internal;
681     }
682     pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
683     pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
684     pTransInfo->inUse = nwal_TRUE;
685     pTransInfo->netapi_handle = h;
687     /* issue request */
688     retValue = nwal_delSecPolicy(
689                 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
690                 trans_id,
691                 handle_policy);
692     if(retValue !=  nwal_OK)
693     {
694         *perr = NETAPI_ERR_NWAL_ERR0;
695         netapip_freeTransInfo(pTransInfo);
696         goto ERR_netapi_secDelRxPolicy_internal;
697     }
699     if(trans_id != NWAL_TRANSID_SPIN_WAIT)
700     {
701         n->nwal_local.numPendingCfg++;
702         while ((pTransInfo->state  !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
703                     (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
704         {
705             nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
706         }
707         if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
708         {
709             netapip_freeTransInfo(pTransInfo);
710             *perr = NETAPI_ERR_PA_FW;
711             //zap the entry
712             if (!flags)
713                 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
714             goto ERR_netapi_secDelRxPolicy_internal;
715             
716         }
717     }
718     netapip_freeTransInfo(pTransInfo);
719     /* zap the entry */
720     if (!flags)
721     {
722         netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
723     }
724 ERR_netapi_secDelRxPolicy_internal:
725     return;
728 /********************************************************************
729  * FUNCTION PURPOSE:  API to delete a receive security policy
730  ********************************************************************
731  * DESCRIPTION:  API to delete a receive security policy
732  ********************************************************************/
733 void netapi_secDelRxPolicy(NETAPI_T h,
734                            NETCP_CFG_IPSEC_POLICY_T policy_app_id,
735                            int *perr)
737     netapi_secDelRxPolicy_internal(h,  policy_app_id, 0, perr);
740 /********************************************************************
741  * FUNCTION PURPOSE:  API to retrieve SA statistics via NWAL
742  ********************************************************************
743  * DESCRIPTION:  API to retrieve SA statistics via NWAL
744  ********************************************************************/
745 void  netapi_getSaStats (NETAPI_T               h, 
746                          NETCP_CFG_SA_T         handle,
747                          NETAPI_SA_STATS_T*     pSaStats)
749     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
750     void * handle_inflow;
751     void * handle_sideband;
752     int tunnelId = (handle >> NETAPI_NETCP_MATCH_ID_SHIFT) &0xffff;
753     int have_to_wait = 1;
754     handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
755                                           tunnelId, &handle_sideband);
756     if(handle_inflow)
757     {
758         nwal_getSecAssocStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
759                                                 handle_inflow, &(pSaStats->saIpsecStats));
760         pSaStats->validParams |= NETAPI_IPSEC_STAT_VALID;
761     }
762     if(handle_sideband)
763     {
764         nwal_getDataModeStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle, 
765                                                 handle_sideband, &(pSaStats->dataModeStats));
766         pSaStats->validParams |= NETAPI_SIDEBAND_DATA_MODE_STAT_VALID;
767     }
771 /**********************************************************************************
772  * FUNCTION PURPOSE:  API to  API to retrieve local channel context information
773  **********************************************************************************
774  * DESCRIPTION:  API to retrieve API to retrieve local channel context information
775  *********************************************************************************/
776 void netapi_secGetChanCtxInfo(NETAPI_T h,
777                            NETCP_CFG_APP_ID_T appId,
778                            nwalChanCxtInfo_t* pInfo)
781     NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
782     void * handle_inflow;
783     void * handle_sideband = NULL;
784     void * handle_policy=NULL;
785     nwalChanCxtInfo_t info;
786     uint32_t stage = 0;
787     int policyId;
788     int tunnelId;
790     if(!pInfo)
791         return;
792     memset(pInfo, 0, sizeof(nwalChanCxtInfo_t));
794     stage = netapi_cfgGetMatchStage(appId);
796     switch (stage)
797     {
798         case 1:
799             /* this is for SA, need SA and OUTER IP handle */
800             tunnelId = netapi_cfgGetMatchId(appId);
801             handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
802                                           tunnelId, &handle_sideband);
803             if(handle_inflow)
804             {
805                 nwal_getChanCxtInfo(&netapi_get_global()->nwal_context,
806                             handle_inflow,
807                             pInfo);
808             }
809             break;
810         case 2:
811             /* this is for policy, need SA inner IP */
812             policyId = netapi_cfgGetMatchId(appId);
813             handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,
814                                                           policyId);
815             if (handle_policy)
816             {
817                 nwal_getChanCxtInfo(&netapi_get_global()->nwal_context,
818                             handle_policy,
819                             pInfo);
820             }
821             break;
822         default:
823             break;
824     }
825     return;