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"
45 /********************************************************************
46 * FUNCTION PURPOSE: API to add an IPSEC SA
47 ********************************************************************
48 * DESCRIPTION: API to add an IPSEC SA
49 ********************************************************************/
50 NETCP_CFG_SA_T netapi_secAddSA(NETAPI_T h,
51 int iface_no,
52 NETAPI_SEC_SA_INFO_T *sa_info,
53 nwalSecKeyParams_t * key_params,
54 int inflow_mode,
55 NETCP_CFG_ROUTE_HANDLE_T route,
56 void **p_data_mode_handle,
57 void **p_inflow_mode_handle,
58 void * p_user_data,
59 int * perr)
60 {
61 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
62 nwal_RetValue retValue;
63 NetapiNwalTransInfo_t *pTransInfo;
64 nwal_TransID_t trans_id;
65 unsigned int appId = NETAPI_NETCP_MATCH_IPSEC | iface_no;
66 int tunnelId;
67 nwalSaIpSecId_t saInfo;
68 int have_to_wait=1;
69 nwalTxDmPSCmdInfo_t dmPSCmdInfo;
70 nwalSaIpSecId_t nwalSaIpSecId;
71 uint32_t swInfo0;
72 uint32_t swInfo1;
74 nwalCreateSAParams_t createParam =
75 {
76 /* mac handle */
77 NULL, //to be filled in
78 4,
79 /*nwalSaIpSecParam_t */
80 {
81 0,/* validParams */
82 nwal_SA_MODE_TUNNEL, //update from input
83 64,/* replayWindow */\
84 NWAL_SA_DIR_INBOUND,
85 0,
86 0,
87 NWAL_SA_AALG_HMAC_SHA1,/* update from input */
88 NWAL_SA_EALG_AES_CTR, /* update from input */
89 { 0x00}, /* remMacAddr: NA */
90 12, /* update from input, mac size */
91 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE,/* Continue parsing to next route for match */
92 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST,/* For next route fail action by default is route to host */
93 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
94 QMSS_PARAM_NOT_SPECIFIED, /* Use default queue configured to NWAL if packet is routed to host */
95 0 /* route type */
96 },
97 /* nwalSaIpSecKeyParams_t */
98 {0}
99 };
102 void * mac_handle = netapip_netcpCfgGetMacHandle(&netapi_get_global()->nwal_context,iface_no);
103 *perr =NETAPI_ERR_OK;
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(n,
112 &netapi_get_global()->nwal_context,
113 iface_no);
115 if (tunnelId <0)
116 {
117 *perr= NETAPI_ERR_NOMEM;
118 return -1;
119 }
120 appId |= (tunnelId << NETAPI_NETCP_MATCH_ID_SHIFT);
121 netapi_Log("netapi_secAddSA: app id: 0x%x\n", appId);
123 *p_data_mode_handle= NULL;
124 *p_inflow_mode_handle= NULL;
128 if (inflow_mode & NETAPI_SEC_SA_INFLOW)
129 {
130 pTransInfo = netapip_getFreeTransInfo(n,
131 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
132 &trans_id);
133 if (!pTransInfo)
134 {
135 *perr = NETAPI_ERR_BUSY;
136 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
137 return -1;
138 }
139 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
140 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
141 pTransInfo->inUse = nwal_TRUE;
142 pTransInfo->netapi_handle = h;
144 /* build SA parameters */
145 saInfo.spi = sa_info->spi;
146 memcpy(&saInfo.dst, &sa_info->dst, sizeof( nwalIpAddr_t));
147 memcpy(&saInfo.src, &sa_info->src, sizeof( nwalIpAddr_t));
148 saInfo.proto = sa_info->proto;
149 createParam.macHandle = mac_handle;
150 createParam.ipType = sa_info->ipType;
151 createParam.saIpSecParam.dir = sa_info->dir;
152 createParam.saIpSecParam.saMode = sa_info->saMode;
153 createParam.saIpSecParam.replayWindow = sa_info->replayWindow;
154 createParam.saIpSecParam.authMode = sa_info->authMode;
155 createParam.saIpSecParam.cipherMode = sa_info->cipherMode;
156 createParam.saIpSecParam.esnLo = sa_info->esnLo;
157 createParam.saIpSecParam.esnHi = sa_info->esnHi;
158 if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
159 (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
160 (sa_info->authMode == NWAL_SA_AALG_GMAC) ||
161 (sa_info->authMode == NWAL_SA_AALG_HMAC_SHA2_256_RFC4868))
162 {
163 createParam.saIpSecParam.macSize = 16;
164 }
165 if ((sa_info->authMode == NWAL_SA_AALG_NULL) &&
166 (!((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
167 (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM))))
168 {
169 createParam.saIpSecParam.replayWindow = 0;
170 createParam.saIpSecParam.macSize = 0;
171 }
172 memcpy(&createParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
174 if (route != NULL)
175 {
176 if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
177 NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
178 {
179 createParam.saIpSecParam.validParams |=
180 NWAL_SA_INFO_VALID_PARAM_ROUTE_TYPE;
181 }
182 netapip_netcpCfgBuildRoute(route,
183 &createParam.saIpSecParam.appRxPktFlowId,
184 &createParam.saIpSecParam.appRxPktQueue,
185 &createParam.saIpSecParam.routeType);
186 }
188 /* fire off config message */
189 retValue = nwal_setSecAssoc (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
190 trans_id,
191 (nwal_AppId) appId,
192 &saInfo,
193 &createParam,
194 &pTransInfo->handle);
195 if(retValue == nwal_TRANS_COMPLETE)
196 {
197 have_to_wait=0;
198 }
199 else if(retValue != nwal_OK)
200 {
201 *perr = NETAPI_ERR_NWAL_ERR0;
202 netapip_freeTransInfo(pTransInfo);
203 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
204 return -1;
205 }
207 if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
208 {
209 n->nwal_local.numPendingCfg++;
210 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
211 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
212 {
213 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
214 }
215 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
216 {
217 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
218 pTransInfo->inUse = nwal_FALSE;
219 *perr = NETAPI_ERR_PA_FW;
220 netapi_Log ("netapi_sec - ERROR returned by NETCP PA firmware %d\n",
221 *perr);
222 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
223 return -1;
224 }
225 }
227 *p_inflow_mode_handle=pTransInfo->handle;
228 netapip_freeTransInfo(pTransInfo);
230 if (sa_info->dir == NWAL_SA_DIR_OUTBOUND)
231 {
232 memset(&nwalSaIpSecId, 0, sizeof(nwalSaIpSecId_t));
233 nwalSaIpSecId.spi = sa_info->spi;
234 memcpy(&(nwalSaIpSecId.src), &sa_info->src,sizeof( nwalIpAddr_t));
235 memcpy(&(nwalSaIpSecId.dst), &sa_info->dst,sizeof( nwalIpAddr_t));
236 nwalSaIpSecId.proto = sa_info->proto;
237 if (nwal_getSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
238 &nwalSaIpSecId,
239 NWAL_SA_DIR_OUTBOUND,
240 p_inflow_mode_handle,
241 &swInfo0,
242 &swInfo1) == nwal_TRUE)
243 {
244 //netapi_Log("netapisecAddSA swInfo0: 0x%x, swInfo1: 0x%x\n", swInfo0, swInfo1);
245 }
246 else
247 netapi_Log("netapisecAddSA: call to nwal_getSecAssoc() returned error\n");
248 }
249 }
251 /* sideband mode */
252 if (inflow_mode &NETAPI_SEC_SA_SIDEBAND)
253 {
254 nwalCreateDmSAParams_t dmSaParam;
255 void * dm_handle;
256 memset(&dmSaParam,0,sizeof(nwalCreateDmSAParams_t));
257 dmSaParam.dmSaParam.dmChnType= (sa_info->dir==NWAL_SA_DIR_INBOUND)? NWAL_DM_CHAN_DECRYPT: NWAL_DM_CHAN_ENCRYPT; /**direction*/
258 dmSaParam.dmSaParam.replayWindow=sa_info->replayWindow;
259 dmSaParam.dmSaParam.authMode=sa_info->authMode;
260 dmSaParam.dmSaParam.cipherMode=sa_info->cipherMode;
261 dmSaParam.dmSaParam.macSize=12;
262 dmSaParam.dmSaParam.aadSize=0;
263 dmSaParam.dmSaParam.enc1st = (sa_info->dir ==NWAL_SA_DIR_OUTBOUND) ? nwal_TRUE : nwal_FALSE; //encypt 1st for outbound
264 if ((sa_info->cipherMode == NWAL_SA_EALG_AES_GCM) ||
265 (sa_info->cipherMode == NWAL_SA_EALG_AES_CCM) ||
266 (sa_info->authMode == NWAL_SA_AALG_GMAC))
267 {
268 dmSaParam.dmSaParam.macSize = 16;
269 dmSaParam.dmSaParam.aadSize=8;
270 /* Enc1st needs to always be true for combined mode algorithms */
271 dmSaParam.dmSaParam.enc1st = nwal_TRUE;
272 }
273 else
274 {
275 dmSaParam.dmSaParam.macSize=12;
276 dmSaParam.dmSaParam.aadSize=0;
277 }
279 if (sa_info->authMode == NWAL_SA_AALG_NULL)
280 {
281 dmSaParam.dmSaParam.enc1st = nwal_TRUE;
282 }
283 /* todo; allow app q for Sideband return */
284 memcpy(&dmSaParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
285 retValue = nwal_setDMSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
286 (nwal_AppId)appId,
287 &dmSaParam,
288 &dm_handle);
289 if(retValue != nwal_OK)
290 {
291 *perr = NETAPI_ERR_NWAL_ERR0;
292 netapi_Log ("netapi_secAddSA: nwal_setDMSecAssoc() returned Error Code %d\n",
293 retValue);
294 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
295 return -1;
296 }
298 //netapi_Log("netapi_secAddSA: Creating sideband mode SA for %d ( mac %d)\n", tunnelId, iface_no);
299 *p_data_mode_handle = dm_handle;
300 memset(&dmPSCmdInfo, 0, sizeof(nwalTxDmPSCmdInfo_t));
301 retValue = nwal_initDMPSCmdInfo(netapip_returnNwalInstanceHandle(h),
302 *p_data_mode_handle,
303 &dmPSCmdInfo);
304 }
306 netapip_netcpCfgInsertSa(&netapi_get_global()->nwal_context,
307 tunnelId,
308 (sa_info->dir == NWAL_SA_DIR_INBOUND) ? TRUE: FALSE,
309 inflow_mode,
310 &saInfo, &createParam,
311 *p_inflow_mode_handle,
312 *p_data_mode_handle,
313 &dmPSCmdInfo,
314 swInfo0,
315 swInfo1,
316 p_user_data);
317 return (appId);
318 }
320 /********************************************************************
321 * FUNCTION PURPOSE: Internal function to dynamically switch between inflow
322 * and sideband mode
323 ********************************************************************
324 * DESCRIPTION: Internal function to dynamically switch between inflow
325 * and sideband mode
326 ********************************************************************/
327 void netapi_secInflowMode(int iface,
328 NETCP_CFG_SA_T sa,
329 int on)
330 {
331 /* NOT_IMPLEMENTED */
332 netapi_Log("netapi_secInflowMode: dynamic switch between inflow and sideband is NOT_IMPLEMENTED\n");
333 }
335 /********************************************************************
336 * FUNCTION PURPOSE: Internal function to delete an IPSEC SA
337 ********************************************************************
338 * DESCRIPTION: Internal function to delete an IPSEC SA
339 ********************************************************************/
340 static void netapi_secDelSA_internal(NETAPI_T h,
341 int iface_no,
342 NETCP_CFG_SA_T sa_app_id,
343 int flags,
344 int *perr)
345 {
346 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
347 nwal_RetValue retValue;
348 NetapiNwalTransInfo_t *pTransInfo;
349 nwal_TransID_t trans_id;
350 int tunnelId = (sa_app_id >> NETAPI_NETCP_MATCH_ID_SHIFT) &NETAPI_NETCP_MATCH_ID_MASK;
351 void * handle_inflow;
352 void * handle_sideband;
353 int have_to_wait = 1;
355 handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
356 tunnelId, &handle_sideband);
357 *perr =0;
359 if(handle_inflow)
360 {
361 /* get a transaction id */
362 pTransInfo = netapip_getFreeTransInfo(n,
363 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
364 &trans_id);
365 if (!pTransInfo)
366 {
367 *perr = NETAPI_ERR_BUSY;
368 return;
369 }
370 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
371 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
372 pTransInfo->inUse = nwal_TRUE;
373 pTransInfo->netapi_handle = h;
375 retValue = nwal_delSecAssoc(
376 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
377 trans_id,
378 handle_inflow);
379 if(retValue == nwal_TRANS_COMPLETE)
380 {
381 have_to_wait=0;
382 }
383 else if(retValue != nwal_OK)
384 {
385 *perr = NETAPI_ERR_NWAL_ERR0;
386 netapi_Log ("netcp_cfg - ERROR: netapi_secDelSA_internal returned Error Code %d\n",
387 retValue);
388 netapip_freeTransInfo(pTransInfo);
389 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context,tunnelId);
390 }
391 if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
392 {
393 n->nwal_local.numPendingCfg++;
395 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
396 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
397 {
398 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
399 }
400 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
401 {
402 netapip_freeTransInfo(pTransInfo);
403 *perr = NETAPI_ERR_PA_FW;
404 if (!flags)
405 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
406 netapi_Log ("netapi_sec - ERROR returned by NETCP PA firmware %d\n",
407 *perr);
408 return;
409 }
410 }
411 netapi_Log ("netapi sec: inflow tunnel %d (iface %d) deleted\n",tunnelId,iface_no);
412 netapip_freeTransInfo(pTransInfo);
413 }
414 if (handle_sideband)
415 {
416 retValue=nwal_delDMSecAssoc( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
417 handle_sideband);
418 if(retValue != nwal_OK)
419 {
420 *perr = NETAPI_ERR_NWAL_ERR0;
421 netapi_Log ("netapi_sec - ERROR: nwal_delDMSA returned Error Code %d\n",
422 retValue);
424 }
425 else
426 netapi_Log("netapi_sec: Sideband SA deleted\n");
427 }
429 /* zap the entry */
430 if (!flags)
431 netapip_netcpCfgDeleteSa(&netapi_get_global()->nwal_context, tunnelId);
432 }
434 /********************************************************************
435 * FUNCTION PURPOSE: API to delete an IPSEC SA
436 ********************************************************************
437 * DESCRIPTION: API to delete an IPSEC SA
438 ********************************************************************/
439 void netapi_secDelSA(NETAPI_T h,
440 int iface_no,
441 NETCP_CFG_SA_T sa_app_id,
442 int *perr)
443 {
444 netapi_secDelSA_internal( h, iface_no, sa_app_id, 0x00, perr);
445 }
448 /********************************************************************
449 * FUNCTION PURPOSE: API to add a receive security policy
450 ********************************************************************
451 * DESCRIPTION: API to add a receive security policy
452 ********************************************************************/
453 NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h,
454 NETCP_CFG_SA_T sa,
455 nwal_IpType ipType,
456 nwalIpAddr_t * src_ip_addr,
457 nwalIpAddr_t * dst_ip_addr,
458 nwalIpOpt_t * ip_qualifiers,
459 NETCP_CFG_ROUTE_HANDLE_T route,
460 void * user_data,
461 int * perr)
462 {
463 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
464 nwal_RetValue retValue;
465 NetapiNwalTransInfo_t *pTransInfo;
466 nwal_TransID_t trans_id;
467 unsigned int appId = NETAPI_NETCP_MATCH_IPSEC_POLICY;
468 int policyId;
469 int tunnelId= netapi_cfgGetMatchId(sa);
470 void * blah;
471 int iface_no = netapi_cfgGetMatchLogicalMacIface(sa);
473 nwalSecPolParams_t createParam =
474 {
475 0, /* handle */
476 0, /* valid params */
477 NWAL_SA_DIR_INBOUND,
478 4, /* IP Type */
479 {0}, /* dst */
480 {0}, /* src */
481 {0 },/* IP Options */
482 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
483 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
484 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
485 QMSS_PARAM_NOT_SPECIFIED, /* Use default queue configured to NWAL if packet is routed to host */
486 0 /* Optional: route type */
487 };
489 void * sa_handle = NULL;
490 *perr =0;
492 if ((!n) )
493 {
494 *perr = NETAPI_ERR_BAD_INPUT;
495 return -1;
496 }
498 sa_handle = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,tunnelId,&blah);
499 if (!sa_handle)
500 {
501 *perr = NETAPI_ERR_BAD_INPUT;
502 return -1;
503 }
505 /* get a transaction id */
506 pTransInfo = netapip_getFreeTransInfo(n,
507 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
508 &trans_id);
509 if (!pTransInfo)
510 {
511 *perr = NETAPI_ERR_BUSY;
512 return -1;
513 }
514 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
515 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
516 pTransInfo->inUse = nwal_TRUE;
517 pTransInfo->netapi_handle = h;
518 createParam.handle = sa_handle;
519 createParam.ipType = ipType;
520 if (dst_ip_addr) memcpy(&createParam.dst, dst_ip_addr, sizeof(nwalIpAddr_t));
521 if (src_ip_addr) memcpy(&createParam.src, src_ip_addr, sizeof(nwalIpAddr_t));
522 if (ip_qualifiers) memcpy(&createParam.ipOpt,ip_qualifiers ,sizeof(nwalIpOpt_t));
523 if (route != NULL)
524 {
525 if((route->valid_params & NETCP_CFG_VALID_PARAM_ROUTE_TYPE) ==
526 NETCP_CFG_VALID_PARAM_ROUTE_TYPE)
527 {
528 createParam.validParams |=
529 NWAL_SET_SEC_POLICY_VALID_PARAM_ROUTE_TYPE;
530 }
531 netapip_netcpCfgBuildRoute(route,
532 &createParam.appRxPktFlowId,
533 &createParam.appRxPktQueue,
534 &createParam.routeType);
535 }
536 /* reserve a slot */
537 policyId = netapip_netcpCfgFindPolicySlot(n,
538 &netapi_get_global()->nwal_context,
539 tunnelId);
540 if (policyId <0)
541 {
542 *perr= NETAPI_ERR_NOMEM;
543 netapip_freeTransInfo(pTransInfo);
544 return -1;
545 }
546 appId |= (policyId <<8);
548 /* fire off config message */
549 retValue = nwal_setSecPolicy (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
550 trans_id,
551 (nwal_AppId) appId,
552 &createParam,
553 &pTransInfo->handle);
554 if(retValue != nwal_OK)
555 {
556 *perr = NETAPI_ERR_NWAL_ERR0;
557 printf("netapi_secAddPolicy: error returned: %d\n", retValue);
558 netapi_Log ("netapi sec - ERROR: nwal_setPolicy returned Error Code %d\n",
559 retValue);
560 netapip_freeTransInfo(pTransInfo);
562 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
563 return -1;
564 }
566 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
567 {
568 n->nwal_local.numPendingCfg++;
569 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
570 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_OPEN))
571 {
572 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
573 }
574 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
575 {
576 netapip_freeTransInfo(pTransInfo);
577 *perr = NETAPI_ERR_PA_FW;
578 netapi_Log ("netapi_sec - ERROR2: netapi_secAddRxPolicy returned Error Code %d\n",
579 *perr);
580 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context,policyId);
581 return -1;
582 }
583 }
584 netapi_Log ("netapi sec: SA %d added to tunnel %d mac %d\n", policyId, tunnelId, iface_no);
586 /* save stuff */
587 netapip_netcpCfgInsertPolicy(&netapi_get_global()->nwal_context,
588 policyId,
589 (void *) pTransInfo->handle,
590 user_data);
591 netapip_freeTransInfo(pTransInfo);
592 return (appId);
593 }
595 /********************************************************************
596 * FUNCTION PURPOSE: Internal function to delete a receive security policy
597 ********************************************************************
598 * DESCRIPTION: Internal function to delete a receive security policy
599 ********************************************************************/
600 static void netapi_secDelRxPolicy_internal(NETAPI_T h,
601 NETCP_CFG_IPSEC_POLICY_T policy_app_id,
602 int flags,
603 int *perr)
604 {
605 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
606 nwal_RetValue retValue;
607 NetapiNwalTransInfo_t *pTransInfo;
608 nwal_TransID_t trans_id;
609 int policyId = netapi_cfgGetMatchId(policy_app_id);
610 void * handle_policy=NULL;
612 handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,policyId);
613 ;
614 if (!handle_policy)
615 {
616 *perr = NETAPI_ERR_BAD_INPUT;
617 goto ERR_netapi_secDelRxPolicy_internal;
618 }
619 *perr =0;
621 /* get a transaction id */
622 pTransInfo = netapip_getFreeTransInfo(n,
623 (NETAPI_PROC_GLOBAL_T *) n->proc_global,
624 &trans_id);
625 if (!pTransInfo)
626 {
627 *perr = NETAPI_ERR_BUSY;
628 goto ERR_netapi_secDelRxPolicy_internal;
629 }
630 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
631 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_CLOSE_PENDING;
632 pTransInfo->inUse = nwal_TRUE;
633 pTransInfo->netapi_handle = h;
635 /* issue request */
636 retValue = nwal_delSecPolicy(
637 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
638 trans_id,
639 handle_policy);
640 if(retValue != nwal_OK)
641 {
642 *perr = NETAPI_ERR_NWAL_ERR0;
643 netapi_Log ("netapi sec - ERROR: netapi_secDelRxPolicy_internal returned Error Code %d\n",
644 retValue);
645 netapip_freeTransInfo(pTransInfo);
646 goto ERR_netapi_secDelRxPolicy_internal;
647 }
649 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
650 {
651 n->nwal_local.numPendingCfg++;
652 while ((pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_ERR) &&
653 (pTransInfo->state !=NETAPI_NWAL_HANDLE_STATE_IDLE))
654 {
655 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
656 }
657 if (pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_ERR)
658 {
659 netapip_freeTransInfo(pTransInfo);
660 *perr = NETAPI_ERR_PA_FW;
661 netapi_Log ("netapi_sec - ERROR2: netapi_secDelRxPolicy_internal returned Error Code %d\n",
662 *perr);
663 //zap the entry
664 if (!flags)
665 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
666 goto ERR_netapi_secDelRxPolicy_internal;
668 }
669 }
670 netapi_Log ("netapi sec: policy %d (iface %d) deleted\n",policyId,(policy_app_id&0xff));
671 netapip_freeTransInfo(pTransInfo);
672 /* zap the entry */
673 if (!flags)
674 {
675 netapip_netcpCfgDeletePolicy(&netapi_get_global()->nwal_context, policyId);
676 }
677 ERR_netapi_secDelRxPolicy_internal:
678 return;
679 }
681 /********************************************************************
682 * FUNCTION PURPOSE: API to delete a receive security policy
683 ********************************************************************
684 * DESCRIPTION: API to delete a receive security policy
685 ********************************************************************/
686 void netapi_secDelRxPolicy(NETAPI_T h,
687 NETCP_CFG_IPSEC_POLICY_T policy_app_id,
688 int *perr)
689 {
690 netapi_secDelRxPolicy_internal(h, policy_app_id, 0, perr);
691 }
693 /********************************************************************
694 * FUNCTION PURPOSE: API to retrieve SA statistics via NWAL
695 ********************************************************************
696 * DESCRIPTION: API to retrieve SA statistics via NWAL
697 ********************************************************************/
698 void netapi_getSaStats (NETAPI_T h,
699 NETCP_CFG_SA_T handle,
700 NETAPI_SA_STATS_T* pSaStats)
701 {
702 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
703 void * handle_inflow;
704 void * handle_sideband;
705 int tunnelId = (handle >> NETAPI_NETCP_MATCH_ID_SHIFT) &0xffff;
706 int have_to_wait = 1;
707 handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
708 tunnelId, &handle_sideband);
709 if(handle_inflow)
710 {
711 nwal_getSecAssocStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
712 handle_inflow, &(pSaStats->saIpsecStats));
713 pSaStats->validParams |= NETAPI_IPSEC_STAT_VALID;
714 }
715 if(handle_sideband)
716 {
717 nwal_getDataModeStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
718 handle_sideband, &(pSaStats->dataModeStats));
719 pSaStats->validParams |= NETAPI_SIDEBAND_DATA_MODE_STAT_VALID;
720 }
721 }
724 /**********************************************************************************
725 * FUNCTION PURPOSE: API to API to retrieve local channel context information
726 **********************************************************************************
727 * DESCRIPTION: API to retrieve API to retrieve local channel context information
728 *********************************************************************************/
729 void netapi_secGetChanCtxInfo(NETAPI_T h,
730 NETCP_CFG_APP_ID_T appId,
731 nwalChanCxtInfo_t* pInfo)
732 {
734 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
735 void * handle_inflow;
736 void * handle_sideband = NULL;
737 void * handle_policy=NULL;
738 nwalChanCxtInfo_t info;
739 uint32_t stage = 0;
740 int policyId;
741 int tunnelId;
743 if(!pInfo)
744 return;
745 memset(pInfo, 0, sizeof(nwalChanCxtInfo_t));
747 stage = netapi_cfgGetMatchStage(appId);
748 netapi_Log("netapi_secGetChanCtxInfo: app id: 0x%x, stage: 0x%x\n", appId, stage);
751 switch (stage)
752 {
753 case 1:
754 /* this is for SA, need SA and OUTER IP handle */
755 tunnelId = netapi_cfgGetMatchId(appId);
756 handle_inflow = netapip_netcpCfgGetSaHandles(&netapi_get_global()->nwal_context,
757 tunnelId, &handle_sideband);
758 if(handle_inflow)
759 {
760 nwal_getChanCxtInfo(&netapi_get_global()->nwal_context,
761 handle_inflow,
762 pInfo);
763 netapi_Log("netapi_secGetChanCtxInfo: outerIP: 0x%x, SA chan handle: 0x%x, bitmap: 0x%x\n",
764 pInfo->paOuterIpHandle, pInfo->saChanHandle, pInfo->validBitMap);
765 }
766 break;
767 case 2:
768 /* this is for policy, need SA inner IP */
769 policyId = netapi_cfgGetMatchId(appId);
770 handle_policy = netapip_netcpCfgGetPolicy(&netapi_get_global()->nwal_context,
771 policyId);
772 if (handle_policy)
773 {
774 nwal_getChanCxtInfo(&netapi_get_global()->nwal_context,
775 handle_policy,
776 pInfo);
777 netapi_Log("netapi_secGetChanCtxInfo: innerIP: 0x%x, bitmap: 0x%x\n",
778 pInfo->paInnerIpHandle, pInfo->validBitMap);
779 }
780 break;
781 default:
782 netapi_Log("netapi_secGetChanCtxInfo:Invalid APPID provided\n");
783 break;
784 }
785 return;
786 }