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 2010-2011
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 *****************************************************************************/
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <string.h>
46 #include "netapi.h"
47 #include "netapi_loc.h"
50 //add a RX Security Association
51 NETCP_CFG_SA_T netapi_secAddSA(NETAPI_T h, //the netapi handle
52 int iface_no, //inteface to attach to
53 NETAPI_SEC_SA_INFO_T *sa_info ,//info on the SA
54 nwalSecKeyParams_t * key_params, //keys,etc
55 int inflow_mode, //SA implementation mode: inflow or sideband or both
56 NETCP_CFG_ROUTE_HANDLE_T route, //Optional route
57 void **p_data_mode_handle,
58 void **p_inflow_mode_handle,
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 nwalCreateSAParams_t createParam =
70 {
71 /* mac handle */
72 NULL, //to be filled in
73 4,
75 /*nwalSaIpSecParam_t */
76 {
77 0,/* validParams */
78 nwal_SA_MODE_TUNNEL, //update from input
79 64,/* replayWindow */
80 NWAL_SA_DIR_INBOUND,
81 0,
82 0,
83 NWAL_SA_AALG_HMAC_SHA1, //update
84 NWAL_SA_EALG_AES_CTR, //update
85 { 0x00}, /* remMacAddr: NA */
86 12, /* macSize */
87 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
88 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
89 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
90 QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */
91 },
92 /* nwalSaIpSecKeyParams_t */
93 {0}
94 };
95 void * mac_handle = netcp_cfgp_get_mac_handle(&netapi_get_global()->nwal_context,iface_no);
97 *perr =0;
98 if ((!n) || (!sa_info) || (!p_data_mode_handle) ) {*perr = NETAPI_ERR_BAD_INPUT; return -1;}
100 //reserve a slot
101 tunnelId = netcp_cfgp_find_sa_slot(&netapi_get_global()->nwal_context,
102 iface_no);
103 if (tunnelId <0) {*perr= NETAPI_ERR_NOMEM; return -1; }
104 appId |= (tunnelId<<8);
106 *p_data_mode_handle= NULL;
107 *p_inflow_mode_handle= NULL;
109 if (inflow_mode & NETAPI_SEC_SA_INFLOW)
110 {
112 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
113 if (!pTransInfo) { *perr = NETAPI_ERR_BUSY;netcp_cfgp_delete_sa(&netapi_get_global()->nwal_context,tunnelId); return -1;}
114 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
115 pTransInfo->netapi_handle = h;
117 /* build SA parameters */
118 saInfo.spi = sa_info->spi;
119 memcpy(&saInfo.dst, &sa_info->dst, sizeof( nwalIpAddr_t));
120 memcpy(&saInfo.src, &sa_info->src, sizeof( nwalIpAddr_t));
121 saInfo.proto = sa_info->proto;
122 createParam.macHandle = mac_handle;
123 createParam.ipType = sa_info->ipType;
124 //memcpy(&createParam.saIpSecParam.src,&sa_info->src, sizeof(nwalIpAddr_t));
125 createParam.saIpSecParam.dir = sa_info->dir;
126 createParam.saIpSecParam.saMode = sa_info->saMode;
127 createParam.saIpSecParam.replayWindow = sa_info->replayWindow;
128 createParam.saIpSecParam.authMode = sa_info->authMode;
129 createParam.saIpSecParam.cipherMode = sa_info->cipherMode;
130 createParam.saIpSecParam.esnLo = sa_info->esnLo;
131 createParam.saIpSecParam.esnHi = sa_info->esnHi;
132 if (sa_info->authMode == NWAL_SA_AALG_NULL)
133 {
134 createParam.saIpSecParam.replayWindow = 0;
135 createParam.saIpSecParam.macSize = 0;
136 }
137 memcpy(&createParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
139 if (route != NULL)
140 {
141 netcp_cfgp_build_route(route,&createParam.saIpSecParam.appRxPktFlowId,
142 &createParam.saIpSecParam.appRxPktQueue);
143 }
145 //fire off config message
146 pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
147 retValue = nwal_setSecAssoc (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
148 trans_id,
149 (nwal_AppId) appId,
150 &saInfo,
151 &createParam,
152 &pTransInfo->handle);
153 if(retValue == nwal_TRANS_COMPLETE)
154 {
155 have_to_wait=0;
156 }
157 else if(retValue != nwal_OK)
158 {
159 *perr = NETAPI_ERR_NWAL_ERR0;
160 printf (">netapi_sec - ERROR: nwal_setSecAssoc returned Error Code %d\n",
161 retValue);
162 pTransInfo->inUse = nwal_FALSE;
163 netcp_cfgp_delete_sa(&netapi_get_global()->nwal_context,tunnelId);
164 return -1;
165 }
166 //pTransInfo->inUse = nwal_FALSE;
168 //wait here until its done since scheduler isn't running yet most likely..
169 // todo: make this handled by scheduler poll later ??
170 if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
171 {
172 n->nwal_local.numPendingCfg++;
173 while ((volatile) n->nwal_local.numPendingCfg)
174 {
175 // if response is there, then this poll squirts out in the CTl poll callback,
176 // which handles the rest (including decrmenting #pending!!
177 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
178 }
179 }
180 printf (">netapi sec: SA %d added to mac %d\n", tunnelId, iface_no);
182 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
183 *p_inflow_mode_handle=pTransInfo->handle;
184 pTransInfo->inUse = nwal_FALSE;
185 }
187 //sideband mode
188 if (inflow_mode &NETAPI_SEC_SA_SIDEBAND)
189 {
190 nwalCreateDmSAParams_t dmSaParam;
191 void * dm_handle;
192 memset(&dmSaParam,0,sizeof(nwalCreateDmSAParams_t));
193 dmSaParam.dmSaParam.dmChnType= (sa_info->dir==NWAL_SA_DIR_INBOUND)? NWAL_DM_CHAN_DECRYPT: NWAL_DM_CHAN_ENCRYPT; /**direction*/
194 dmSaParam.dmSaParam.replayWindow=sa_info->replayWindow; /**< Replay Window Size */
195 dmSaParam.dmSaParam.authMode=sa_info->authMode; /**< Authentication Algorithm */
196 dmSaParam.dmSaParam.cipherMode=sa_info->cipherMode ; /**< Encryption Algorithm */
197 dmSaParam.dmSaParam.macSize=12; /**todo: pass in or deduce */
198 dmSaParam.dmSaParam.aadSize=0; /**todo: pass in or deduce */
199 dmSaParam.dmSaParam.enc1st = (sa_info->dir ==NWAL_SA_DIR_OUTBOUND) ? nwal_TRUE : nwal_FALSE; //encypt 1st for outbound
200 if (sa_info->authMode == NWAL_SA_AALG_NULL)
201 {
202 dmSaParam.dmSaParam.enc1st = nwal_TRUE;
203 }
204 //todo; allow app q for Sideband return
205 memcpy(&dmSaParam.keyParam,key_params,sizeof(nwalSecKeyParams_t));
206 retValue = nwal_setDMSecAssoc(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
207 (nwal_AppId)appId,
208 &dmSaParam,
209 &dm_handle);
210 if(retValue != nwal_OK)
211 {
212 *perr = NETAPI_ERR_NWAL_ERR0;
213 printf (">netapi_sec - ERROR: nwal_setDMSecAssoc returned Error Code %d\n",
214 retValue);
215 netcp_cfgp_delete_sa(&netapi_get_global()->nwal_context,tunnelId);
216 return -1;
217 }
218 printf(">netapisec. Creating sideband mode SA for %d ( mac %d)\n", tunnelId, iface_no);
219 *p_data_mode_handle = dm_handle;
220 }
221 //save stuff
222 netcp_cfgp_insert_sa(&netapi_get_global()->nwal_context,
223 tunnelId,
224 (sa_info->dir == NWAL_SA_DIR_INBOUND) ? TRUE: FALSE,
225 inflow_mode,
226 &saInfo, &createParam,
227 *p_inflow_mode_handle,
228 *p_data_mode_handle);
229 return (appId);
230 }
232 //enable or disable inflow mode
233 void netapi_secInflowMode(int iface, NETCP_CFG_SA_T sa, int on)
234 {
235 /*todo */ /* FUTURE */
236 printf(">netapi_sec: dynamic switch between inflow and sideband is not functional yet\n");
237 }
239 //delete the SA
240 //(internal version)
241 static void netapi_secDelSA_internal(NETAPI_T h,int iface_no, NETCP_CFG_SA_T sa_app_id, int flags, int *perr)
242 {
243 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
244 nwal_RetValue retValue;
245 NetapiNwalTransInfo_t *pTransInfo;
246 nwal_TransID_t trans_id;
247 int tunnelId = (sa_app_id >>8) &0xffff;
248 void * handle_inflow;
249 void * handle_sideband;
250 int have_to_wait = 1;
252 handle_inflow = netcp_cfgp_get_sa_handles(&netapi_get_global()->nwal_context,
253 tunnelId, &handle_sideband);
254 *perr =0;
256 if(handle_inflow)
257 {
258 //get a transaction id
259 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
260 if (!pTransInfo) { *perr = NETAPI_ERR_BUSY; return ;}
261 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA;
262 pTransInfo->netapi_handle = h;
264 //issue request
265 retValue = nwal_delSecAssoc(
266 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
267 trans_id,
268 handle_inflow);
269 if(retValue == nwal_TRANS_COMPLETE)
270 {
271 have_to_wait=0;
272 }
273 else
274 if(retValue != nwal_OK)
275 {
276 *perr = NETAPI_ERR_NWAL_ERR0;
277 printf (">netapi_sec - ERROR: nwal_delSA returned Error Code %d\n",
278 retValue);
279 pTransInfo->inUse = nwal_FALSE;
280 return ;
281 }
282 //wait here until its done since scheduler isn't running yet most likely..
283 // todo: make this handled by scheduler poll later ??
284 if((trans_id != NWAL_TRANSID_SPIN_WAIT)&&(have_to_wait))
285 {
286 n->nwal_local.numPendingCfg++;
287 while ((volatile) n->nwal_local.numPendingCfg)
288 {
289 // if response is there, then this poll squirts out in the CTl poll callback,
290 // which handles the rest (including decrmenting #pending!!
291 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
292 }
293 }
294 printf (">netapi sec: inflow tunnel %d (iface %d) deleted\n",tunnelId,iface_no);
295 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
296 pTransInfo->inUse = nwal_FALSE;
297 }
298 if (handle_sideband)
299 {
300 retValue=nwal_delDMSecAssoc( ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
301 handle_sideband);
302 if(retValue != nwal_OK)
303 {
304 *perr = NETAPI_ERR_NWAL_ERR0;
305 printf (">netapi_sec - ERROR: nwal_delDMSA returned Error Code %d\n",
306 retValue);
308 }
309 else printf(">netapi_sec: Sideband SA deleted\n");
310 }
312 //zap the entry
313 if (!flags) netcp_cfgp_delete_sa(&netapi_get_global()->nwal_context, tunnelId);
314 }
315 //external version
316 void netapi_secDelSA(NETAPI_T h,int iface_no, NETCP_CFG_SA_T sa_app_id, int *perr)
317 {
318 netapi_secDelSA_internal( h, iface_no, sa_app_id, 0x00, perr);
319 }
322 //******************************************
323 // Add Policy
324 //******************************************
325 NETCP_CFG_IPSEC_POLICY_T netapi_secAddRxPolicy(NETAPI_T h, //the netapi handle
326 NETCP_CFG_SA_T sa, //tunnel to attach to
327 nwal_IpType ipType, //V4 or V6
328 nwalIpAddr_t * src_ip_addr, //src (from where)
329 nwalIpAddr_t * dst_ip_addr, //dst (us)
330 nwalIpOpt_t * ip_qualifiers, //other qualifiers
331 NETCP_CFG_ROUTE_HANDLE_T route, //Optional route
332 int * perr)
333 {
334 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
335 nwal_RetValue retValue;
336 NetapiNwalTransInfo_t *pTransInfo;
337 nwal_TransID_t trans_id;
338 unsigned int appId = NETAPI_NETCP_MATCH_IPSEC_POLICY | (sa&0xff);
339 int policyId;
340 int tunnelId= (sa>>8)&0xff;
341 void * blah;
342 int iface_no = sa&0xff;
343 nwalSecPolParams_t createParam =
344 {
345 0, /* handle */
346 NWAL_SA_DIR_INBOUND,
347 4, /* IP Type */
348 {0}, /* dst */
349 {0}, /* src */
350 {0 },/* IP Options */
351 NWAL_MATCH_ACTION_CONTINUE_NEXT_ROUTE, /* Continue parsing to next route for match */
352 NWAL_NEXT_ROUTE_FAIL_ACTION_HOST, /* For next route fail action by default is route to host */
353 CPPI_PARAM_NOT_SPECIFIED, /* Use default flow configured to NWAL if packet is routed to host */
354 QMSS_PARAM_NOT_SPECIFIED /* Use default queue configured to NWAL if packet is routed to host */
355 };
356 void * sa_handle = NULL;
358 *perr =0;
359 if ((!n) ) {*perr = NETAPI_ERR_BAD_INPUT; return -1;}
361 sa_handle = netcp_cfgp_get_sa_handles(&netapi_get_global()->nwal_context,tunnelId,&blah);
362 if (!sa_handle) {*perr = NETAPI_ERR_BAD_INPUT; return -1;}
364 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
365 if (!pTransInfo) { *perr = NETAPI_ERR_BUSY; return -1;}
366 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
367 pTransInfo->netapi_handle = h;
368 createParam.handle = sa_handle;
369 createParam.ipType = ipType;
370 if (dst_ip_addr) memcpy(&createParam.dst, dst_ip_addr, sizeof(nwalIpAddr_t));
371 if (src_ip_addr) memcpy(&createParam.src, src_ip_addr, sizeof(nwalIpAddr_t));
372 if (ip_qualifiers) memcpy(&createParam.ipOpt,ip_qualifiers ,sizeof(nwalIpOpt_t));
373 if (route != NULL)
374 {
375 netcp_cfgp_build_route(route,&createParam.appRxPktFlowId,
376 &createParam.appRxPktQueue);
377 }
378 //reserve a slot
379 policyId = netcp_cfgp_find_policy_slot(&netapi_get_global()->nwal_context,
380 tunnelId);
381 if (policyId <0) {*perr= NETAPI_ERR_NOMEM; return -1; }
382 appId |= (policyId<<8);
384 //fire off config message
385 pTransInfo->state == NETAPI_NWAL_HANDLE_STATE_OPEN_PENDING;
387 retValue = nwal_setSecPolicy (((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
388 trans_id,
389 (nwal_AppId) appId,
390 &createParam,
391 &pTransInfo->handle);
392 if(retValue != nwal_OK)
393 {
394 *perr = NETAPI_ERR_NWAL_ERR0;
395 printf (">netapi sec - ERROR: nwal_setPolicy returned Error Code %d\n",
396 retValue);
397 pTransInfo->inUse = nwal_FALSE;
398 netcp_cfgp_delete_policy(&netapi_get_global()->nwal_context,policyId);
399 return -1;
400 }
401 //pTransInfo->inUse = nwal_FALSE;
403 //wait here until its done since scheduler isn't running yet most likely..
404 // todo: make this handled by scheduler poll later ??
405 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
406 {
407 n->nwal_local.numPendingCfg++;
408 while ((volatile) n->nwal_local.numPendingCfg)
409 {
410 // if response is there, then this poll squirts out in the CTl poll callback,
411 // which handles the rest (including decrmenting #pending!!
412 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
413 }
414 }
415 printf (">netapi sec: SA %d added to tunnel %d mac %d\n", policyId, tunnelId, iface_no);
417 //todo: the sideband i/f
419 //save stuff
420 netcp_cfgp_insert_policy(&netapi_get_global()->nwal_context,
421 policyId,
422 (void *) pTransInfo->handle);
423 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
424 pTransInfo->inUse = nwal_FALSE;
425 return (appId);
426 }
428 //************************
429 //Delete Policy (internal)
430 //***********************
431 static void netapi_secDelRxPolicy_internal(NETAPI_T h, NETCP_CFG_IPSEC_POLICY_T policy_app_id, int flags, int *perr)
432 {
433 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
434 nwal_RetValue retValue;
435 NetapiNwalTransInfo_t *pTransInfo;
436 nwal_TransID_t trans_id;
437 int policyId = (policy_app_id >>8) &0xffff;
438 void * handle_policy=NULL;
440 handle_policy = netcp_cfgp_get_policy(&netapi_get_global()->nwal_context,policyId);
441 ;
442 if (!handle_policy) {*perr = NETAPI_ERR_BAD_INPUT; return ;}
443 *perr =0;
445 //get a transaction id
446 pTransInfo = netapip_GetFreeTransInfo((NETAPI_GLOBAL_T *) n->global, &trans_id);
447 if (!pTransInfo) { *perr = NETAPI_ERR_BUSY; return ;}
448 pTransInfo->transType = NETAPI_NWAL_HANDLE_TRANS_SA_POLICY;
449 pTransInfo->netapi_handle = h;
451 //issue request
452 retValue = nwal_delSecPolicy(
453 ((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
454 trans_id,
455 handle_policy);
456 if(retValue != nwal_OK)
457 {
458 *perr = NETAPI_ERR_NWAL_ERR0;
459 printf (">netsec - ERROR: nwal_delSAPolicy returned Error Code %d\n",
460 retValue);
461 pTransInfo->inUse = nwal_FALSE;
462 return ;
463 }
464 //wait here until its done since scheduler isn't running yet most likely..
465 // todo: make this handled by scheduler poll later ??
466 if(trans_id != NWAL_TRANSID_SPIN_WAIT)
467 {
468 n->nwal_local.numPendingCfg++;
469 while ((volatile) n->nwal_local.numPendingCfg)
470 {
471 // if response is there, then this poll squirts out in the CTl poll callback,
472 // which handles the rest (including decrmenting #pending!!
473 nwal_pollCtl(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,NULL,NULL);
474 }
475 }
476 printf (">netapi sec: policy %d (iface %d) deleted\n",policyId,(policy_app_id&0xff));
477 pTransInfo->state = NETAPI_NWAL_HANDLE_STATE_IDLE;
478 pTransInfo->inUse = nwal_FALSE;
479 //zap the entry
480 if (!flags) netcp_cfgp_delete_policy(&netapi_get_global()->nwal_context, policyId);
481 }
483 //************************
484 //Delete Policy
485 //***********************
486 void netapi_secDelRxPolicy(NETAPI_T h, NETCP_CFG_IPSEC_POLICY_T policy_app_id, int *perr)
487 {
488 netapi_secDelRxPolicy_internal(h, policy_app_id, 0, perr);
489 }
493 void netapi_getSaStats (NETAPI_T h,
494 NETCP_CFG_SA_T handle,
495 NETAPI_SA_STATS_T* pSaStats)
496 {
498 NETAPI_HANDLE_T * n = (NETAPI_HANDLE_T *) h;
499 void * handle_inflow;
500 void * handle_sideband;
501 int tunnelId = (handle >>8) &0xffff;
502 int have_to_wait = 1;
503 handle_inflow = netcp_cfgp_get_sa_handles(&netapi_get_global()->nwal_context,
504 tunnelId, &handle_sideband);
505 if(handle_inflow)
506 {
507 //printf("netapi_getSaStats(): handle inflow valid\n");
508 nwal_getSecAssocStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
509 handle_inflow, &(pSaStats->saIpsecStats));
510 pSaStats->validParams |= NETAPI_IPSEC_STAT_VALID;
511 }
512 if(handle_sideband)
513 {
514 //printf("netapi_getSaStats(): handle sideband valid\n");
515 nwal_getDataModeStats(((NETAPI_GLOBAL_T*) (n->global))->nwal_context.nwalInstHandle,
516 handle_sideband, &(pSaStats->dataModeStats));
517 pSaStats->validParams |= NETAPI_SIDEBAND_DATA_MODE_STAT_VALID;
518 }
520 }