• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 		* Redistributions of source code must retain the above copyright
8 			notice, this list of conditions and the following disclaimer.
9 		* Redistributions in binary form must reproduce the above
10 			copyright notice, this list of conditions and the following
11 			disclaimer in the documentation and/or other materials provided
12 			with the distribution.
13 		* Neither the name of The Linux Foundation nor the names of its
14 			contributors may be used to endorse or promote products derived
15 			from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 /*!
30 	@file
31 	IPACM_Filtering.cpp
32 
33 	@brief
34 	This file implements the IPACM filtering functionality.
35 
36 	@Author
37 	Skylar Chang
38 
39 */
40 #include <unistd.h>
41 #include <sys/ioctl.h>
42 #include <fcntl.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 
46 #include "IPACM_Filtering.h"
47 #include <IPACM_Log.h>
48 #include "IPACM_Defs.h"
49 #include "IPACM_Iface.h"
50 
51 
52 const char *IPACM_Filtering::DEVICE_NAME = "/dev/ipa";
53 
IPACM_Filtering()54 IPACM_Filtering::IPACM_Filtering()
55 {
56 	fd = open(DEVICE_NAME, O_RDWR);
57 	if (fd < 0)
58 	{
59 		IPACMERR("Failed opening %s.\n", DEVICE_NAME);
60 	}
61 	total_num_offload_rules = 0;
62 	pcie_modem_rule_id = 0;
63 }
64 
~IPACM_Filtering()65 IPACM_Filtering::~IPACM_Filtering()
66 {
67 	close(fd);
68 }
69 
DeviceNodeIsOpened()70 bool IPACM_Filtering::DeviceNodeIsOpened()
71 {
72 	return fd;
73 }
74 
AddFilteringRule(struct ipa_ioc_add_flt_rule const * ruleTable)75 bool IPACM_Filtering::AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTable)
76 {
77 	int retval = 0;
78 
79 	IPACMDBG("Printing filter add attributes\n");
80 	IPACMDBG("ip type: %d\n", ruleTable->ip);
81 	IPACMDBG("Number of rules: %d\n", ruleTable->num_rules);
82 	IPACMDBG("End point: %d and global value: %d\n", ruleTable->ep, ruleTable->global);
83 	IPACMDBG("commit value: %d\n", ruleTable->commit);
84 	for (int cnt=0; cnt<ruleTable->num_rules; cnt++)
85 	{
86 		IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", cnt,
87 				ruleTable->rules[cnt].rule.attrib.attrib_mask);
88 	}
89 
90 	retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE, ruleTable);
91 	if (retval != 0)
92 	{
93 		IPACMERR("Failed adding Filtering rule %pK\n", ruleTable);
94 		PERROR("unable to add filter rule:");
95 
96 		for (int cnt = 0; cnt < ruleTable->num_rules; cnt++)
97 		{
98 			if (ruleTable->rules[cnt].status != 0)
99 			{
100 				IPACMERR("Adding Filter rule:%d failed with status:%d\n",
101 								 cnt, ruleTable->rules[cnt].status);
102 			}
103 		}
104 		return false;
105 	}
106 
107 	for (int cnt = 0; cnt<ruleTable->num_rules; cnt++)
108 	{
109 		if(ruleTable->rules[cnt].status != 0)
110 		{
111 			IPACMERR("Adding Filter rule:%d failed with status:%d\n",
112 							 cnt, ruleTable->rules[cnt].status);
113 		}
114 	}
115 
116 	IPACMDBG("Added Filtering rule %pK\n", ruleTable);
117 	return true;
118 }
119 
120 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
AddFilteringRule_hw_index(struct ipa_ioc_add_flt_rule * ruleTable,int hw_counter_index)121 bool IPACM_Filtering::AddFilteringRule_hw_index(struct ipa_ioc_add_flt_rule *ruleTable, int hw_counter_index)
122 {
123 	int retval=0, cnt = 0, len = 0;
124 	struct ipa_ioc_add_flt_rule_v2 *ruleTable_v2;
125 	struct ipa_flt_rule_add_v2 flt_rule_entry;
126 	bool ret = true;
127 
128 	IPACMDBG("Printing filter add attributes\n");
129 	IPACMDBG("ip type: %d\n", ruleTable->ip);
130 	IPACMDBG("Number of rules: %d\n", ruleTable->num_rules);
131 	IPACMDBG("End point: %d and global value: %d\n", ruleTable->ep, ruleTable->global);
132 	IPACMDBG("commit value: %d\n", ruleTable->commit);
133 
134 	/* change to v2 format*/
135 	len = sizeof(struct ipa_ioc_add_flt_rule_v2);
136 	ruleTable_v2 = (struct ipa_ioc_add_flt_rule_v2*)malloc(len);
137 	if (ruleTable_v2 == NULL)
138 	{
139 		IPACMERR("Error Locate ipa_ioc_add_flt_rule_v2 memory...\n");
140 		return false;
141 	}
142 	memset(ruleTable_v2, 0, len);
143 	ruleTable_v2->rules = (uint64_t)calloc(ruleTable->num_rules, sizeof(struct ipa_flt_rule_add_v2));
144 	if (!ruleTable_v2->rules) {
145 		IPACMERR("Failed to allocate memory for filtering rules\n");
146 		ret = false;
147 		goto fail_tbl;
148 	}
149 
150 	ruleTable_v2->commit = ruleTable->commit;
151 	ruleTable_v2->ep = ruleTable->ep;
152 	ruleTable_v2->global = ruleTable->global;
153 	ruleTable_v2->ip = ruleTable->ip;
154 	ruleTable_v2->num_rules = ruleTable->num_rules;
155 	ruleTable_v2->flt_rule_size = sizeof(struct ipa_flt_rule_add_v2);
156 
157 	for (cnt=0; cnt < ruleTable->num_rules; cnt++)
158 	{
159 		memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add_v2));
160 		flt_rule_entry.at_rear = ruleTable->rules[cnt].at_rear;
161 		flt_rule_entry.rule.retain_hdr = ruleTable->rules[cnt].rule.retain_hdr;
162 		flt_rule_entry.rule.to_uc = ruleTable->rules[cnt].rule.to_uc;
163 		flt_rule_entry.rule.action = ruleTable->rules[cnt].rule.action;
164 		flt_rule_entry.rule.rt_tbl_hdl = ruleTable->rules[cnt].rule.rt_tbl_hdl;
165 		flt_rule_entry.rule.rt_tbl_idx = ruleTable->rules[cnt].rule.rt_tbl_idx;
166 		flt_rule_entry.rule.eq_attrib_type = ruleTable->rules[cnt].rule.eq_attrib_type;
167 		flt_rule_entry.rule.max_prio = ruleTable->rules[cnt].rule.max_prio;
168 		flt_rule_entry.rule.hashable = ruleTable->rules[cnt].rule.hashable;
169 		flt_rule_entry.rule.rule_id = ruleTable->rules[cnt].rule.rule_id;
170 		flt_rule_entry.rule.set_metadata = ruleTable->rules[cnt].rule.set_metadata;
171 		flt_rule_entry.rule.pdn_idx = ruleTable->rules[cnt].rule.pdn_idx;
172 		memcpy(&flt_rule_entry.rule.eq_attrib,
173 					 &ruleTable->rules[cnt].rule.eq_attrib,
174 					 sizeof(flt_rule_entry.rule.eq_attrib));
175 		memcpy(&flt_rule_entry.rule.attrib,
176 					 &ruleTable->rules[cnt].rule.attrib,
177 					 sizeof(flt_rule_entry.rule.attrib));
178 		IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", cnt,
179 				ruleTable->rules[cnt].rule.attrib.attrib_mask);
180 		/* 0 means disable hw-counter-sats */
181 		if (hw_counter_index != 0)
182 		{
183 			flt_rule_entry.rule.enable_stats = 1;
184 			flt_rule_entry.rule.cnt_idx = hw_counter_index;
185 		}
186 
187 		/* copy to v2 table*/
188 		memcpy((void *)(ruleTable_v2->rules + (cnt * sizeof(struct ipa_flt_rule_add_v2))),
189 			&flt_rule_entry, sizeof(flt_rule_entry));
190 	}
191 
192 	retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_V2, ruleTable_v2);
193 	if (retval != 0)
194 	{
195 		IPACMERR("Failed adding Filtering rule %pK\n", ruleTable_v2);
196 		PERROR("unable to add filter rule:");
197 
198 		for (int cnt = 0; cnt < ruleTable_v2->num_rules; cnt++)
199 		{
200 			if (((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
201 			{
202 				IPACMERR("Adding Filter rule:%d failed with status:%d\n",
203 								 cnt, ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status);
204 			}
205 		}
206 		ret = false;
207 		goto fail_rule;
208 	}
209 
210 	/* copy results from v2 to v1 format */
211 	for (int cnt = 0; cnt < ruleTable->num_rules; cnt++)
212 	{
213 		/* copy status to v1 format */
214 		ruleTable->rules[cnt].status = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status;
215 		ruleTable->rules[cnt].flt_rule_hdl = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].flt_rule_hdl;
216 
217 		if(((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
218 		{
219 			IPACMERR("Adding Filter rule:%d failed with status:%d\n",
220 							 cnt, ((struct ipa_flt_rule_add_v2 *) ruleTable_v2->rules)[cnt].status);
221 		}
222 	}
223 
224 	IPACMDBG("Added Filtering rule %pK\n", ruleTable_v2);
225 
226 fail_rule:
227 	if((void *)ruleTable_v2->rules != NULL)
228 		free((void *)ruleTable_v2->rules);
229 fail_tbl:
230 	if (ruleTable_v2 != NULL)
231 		free(ruleTable_v2);
232 	return ret;
233 }
234 
AddFilteringRuleAfter_hw_index(struct ipa_ioc_add_flt_rule_after * ruleTable,int hw_counter_index)235 bool IPACM_Filtering::AddFilteringRuleAfter_hw_index(struct ipa_ioc_add_flt_rule_after *ruleTable, int hw_counter_index)
236 {
237 	bool ret = true;
238 	int retval=0, cnt = 0, len = 0;
239 	struct ipa_ioc_add_flt_rule_after_v2 *ruleTable_v2;
240 	struct ipa_flt_rule_add_v2 flt_rule_entry;
241 
242 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
243 	{
244 		IPACMDBG("Printing filter add attributes\n");
245 		IPACMDBG("ep: %d\n", ruleTable->ep);
246 		IPACMDBG("ip type: %d\n", ruleTable->ip);
247 		IPACMDBG("Number of rules: %d\n", ruleTable->num_rules);
248 		IPACMDBG("add_after_hdl: %d\n", ruleTable->add_after_hdl);
249 		IPACMDBG("commit value: %d\n", ruleTable->commit);
250 
251 		/* change to v2 format*/
252 		len = sizeof(struct ipa_ioc_add_flt_rule_after_v2);
253 		ruleTable_v2 = (struct ipa_ioc_add_flt_rule_after_v2*)malloc(len);
254 		if (ruleTable_v2 == NULL)
255 		{
256 			IPACMERR("Error Locate ipa_ioc_add_flt_rule_after_v2 memory...\n");
257 			return false;
258 		}
259 		memset(ruleTable_v2, 0, len);
260 		ruleTable_v2->rules = (uint64_t)calloc(ruleTable->num_rules, sizeof(struct ipa_flt_rule_add_v2));
261 		if (!ruleTable_v2->rules) {
262 			IPACMERR("Failed to allocate memory for filtering rules\n");
263 			ret = false;
264 			goto fail_tbl;
265 		}
266 
267 		ruleTable_v2->commit = ruleTable->commit;
268 		ruleTable_v2->ep = ruleTable->ep;
269 		ruleTable_v2->ip = ruleTable->ip;
270 		ruleTable_v2->num_rules = ruleTable->num_rules;
271 		ruleTable_v2->add_after_hdl = ruleTable->add_after_hdl;
272 		ruleTable_v2->flt_rule_size = sizeof(struct ipa_flt_rule_add_v2);
273 
274 		for (cnt=0; cnt < ruleTable->num_rules; cnt++)
275 		{
276 			memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add_v2));
277 			flt_rule_entry.at_rear = ruleTable->rules[cnt].at_rear;
278 			flt_rule_entry.rule.retain_hdr = ruleTable->rules[cnt].rule.retain_hdr;
279 			flt_rule_entry.rule.to_uc = ruleTable->rules[cnt].rule.to_uc;
280 			flt_rule_entry.rule.action = ruleTable->rules[cnt].rule.action;
281 			flt_rule_entry.rule.rt_tbl_hdl = ruleTable->rules[cnt].rule.rt_tbl_hdl;
282 			flt_rule_entry.rule.rt_tbl_idx = ruleTable->rules[cnt].rule.rt_tbl_idx;
283 			flt_rule_entry.rule.eq_attrib_type = ruleTable->rules[cnt].rule.eq_attrib_type;
284 			flt_rule_entry.rule.max_prio = ruleTable->rules[cnt].rule.max_prio;
285 			flt_rule_entry.rule.hashable = ruleTable->rules[cnt].rule.hashable;
286 			flt_rule_entry.rule.rule_id = ruleTable->rules[cnt].rule.rule_id;
287 			flt_rule_entry.rule.set_metadata = ruleTable->rules[cnt].rule.set_metadata;
288 			flt_rule_entry.rule.pdn_idx = ruleTable->rules[cnt].rule.pdn_idx;
289 			memcpy(&flt_rule_entry.rule.eq_attrib,
290 						 &ruleTable->rules[cnt].rule.eq_attrib,
291 						 sizeof(flt_rule_entry.rule.eq_attrib));
292 			memcpy(&flt_rule_entry.rule.attrib,
293 						 &ruleTable->rules[cnt].rule.attrib,
294 						 sizeof(flt_rule_entry.rule.attrib));
295 			IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", cnt,
296 					ruleTable->rules[cnt].rule.attrib.attrib_mask);
297 			/* 0 means disable hw-counter-sats */
298 			if (hw_counter_index != 0)
299 			{
300 				flt_rule_entry.rule.enable_stats = 1;
301 				flt_rule_entry.rule.cnt_idx = hw_counter_index;
302 			}
303 
304 			/* copy to v2 table*/
305 			memcpy((void *)(ruleTable_v2->rules + (cnt * sizeof(struct ipa_flt_rule_add_v2))),
306 				&flt_rule_entry, sizeof(flt_rule_entry));
307 		}
308 
309 		retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_AFTER_V2, ruleTable_v2);
310 		if (retval != 0)
311 		{
312 			IPACMERR("Failed adding Filtering rule %pK\n", ruleTable_v2);
313 			PERROR("unable to add filter rule:");
314 
315 			for (int cnt = 0; cnt < ruleTable_v2->num_rules; cnt++)
316 			{
317 				if (((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
318 				{
319 					IPACMERR("Adding Filter rule:%d failed with status:%d\n",
320 									 cnt, ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status);
321 				}
322 			}
323 			ret = false;
324 			goto fail_rule;
325 		}
326 
327 		/* copy results from v2 to v1 format */
328 		for (int cnt = 0; cnt < ruleTable->num_rules; cnt++)
329 		{
330 			/* copy status to v1 format */
331 			ruleTable->rules[cnt].status = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status;
332 			ruleTable->rules[cnt].flt_rule_hdl = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].flt_rule_hdl;
333 
334 			if(((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
335 			{
336 				IPACMERR("Adding Filter rule:%d failed with status:%d\n",
337 								 cnt, ((struct ipa_flt_rule_add_v2 *) ruleTable_v2->rules)[cnt].status);
338 			}
339 		}
340 
341 		IPACMDBG("Added Filtering rule %pK\n", ruleTable_v2);
342 
343 	fail_rule:
344 		if((void *)ruleTable_v2->rules != NULL)
345 			free((void *)ruleTable_v2->rules);
346 	fail_tbl:
347 		if (ruleTable_v2 != NULL)
348 			free(ruleTable_v2);
349 	}
350 	else
351 	{
352 		if (ruleTable)
353 			IPACMERR("Not support adding Filtering rule %pK\n", ruleTable);
354 	}
355 	return ret;
356 }
357 #endif //IPA_IOCTL_SET_FNR_COUNTER_INFO
358 
AddFilteringRuleAfter(struct ipa_ioc_add_flt_rule_after const * ruleTable)359 bool IPACM_Filtering::AddFilteringRuleAfter(struct ipa_ioc_add_flt_rule_after const *ruleTable)
360 {
361 	int retval = 0;
362 
363 	if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
364 	{
365 		IPACMDBG("Printing filter add attributes\n");
366 		IPACMDBG("ip type: %d\n", ruleTable->ip);
367 		IPACMDBG("Number of rules: %d\n", ruleTable->num_rules);
368 		IPACMDBG("End point: %d\n", ruleTable->ep);
369 		IPACMDBG("commit value: %d\n", ruleTable->commit);
370 
371 		retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_AFTER, ruleTable);
372 
373 		for (int cnt = 0; cnt<ruleTable->num_rules; cnt++)
374 		{
375 			if(ruleTable->rules[cnt].status != 0)
376 			{
377 				IPACMERR("Adding Filter rule:%d failed with status:%d\n",
378 								 cnt, ruleTable->rules[cnt].status);
379 			}
380 		}
381 
382 		if (retval != 0)
383 		{
384 			IPACMERR("Failed adding Filtering rule %pK\n", ruleTable);
385 			return false;
386 		}
387 		IPACMDBG("Added Filtering rule %pK\n", ruleTable);
388 	}
389 	else
390 	{
391 		if (ruleTable)
392 			IPACMERR("Not support adding Filtering rule %pK\n", ruleTable);
393 	}
394 	return true;
395 }
396 
DeleteFilteringRule(struct ipa_ioc_del_flt_rule * ruleTable)397 bool IPACM_Filtering::DeleteFilteringRule(struct ipa_ioc_del_flt_rule *ruleTable)
398 {
399 	int retval = 0;
400 
401 	retval = ioctl(fd, IPA_IOC_DEL_FLT_RULE, ruleTable);
402 	if (retval != 0)
403 	{
404 		IPACMERR("Failed deleting Filtering rule %pK\n", ruleTable);
405 		return false;
406 	}
407 
408 	IPACMDBG("Deleted Filtering rule %pK\n", ruleTable);
409 	return true;
410 }
411 
Commit(enum ipa_ip_type ip)412 bool IPACM_Filtering::Commit(enum ipa_ip_type ip)
413 {
414 	int retval = 0;
415 
416 	retval = ioctl(fd, IPA_IOC_COMMIT_FLT, ip);
417 	if (retval != 0)
418 	{
419 		IPACMERR("failed committing Filtering rules.\n");
420 		return false;
421 	}
422 
423 	IPACMDBG("Committed Filtering rules to IPA HW.\n");
424 	return true;
425 }
426 
Reset(enum ipa_ip_type ip)427 bool IPACM_Filtering::Reset(enum ipa_ip_type ip)
428 {
429 	int retval = 0;
430 
431 	retval = ioctl(fd, IPA_IOC_RESET_FLT, ip);
432 	retval |= ioctl(fd, IPA_IOC_COMMIT_FLT, ip);
433 	if (retval)
434 	{
435 		IPACMERR("failed resetting Filtering block.\n");
436 		return false;
437 	}
438 
439 	IPACMDBG("Reset command issued to IPA Filtering block.\n");
440 	return true;
441 }
442 
DeleteFilteringHdls(uint32_t * flt_rule_hdls,ipa_ip_type ip,uint8_t num_rules)443 bool IPACM_Filtering::DeleteFilteringHdls
444 (
445 	 uint32_t *flt_rule_hdls,
446 	 ipa_ip_type ip,
447 	 uint8_t num_rules
448 )
449 {
450 	struct ipa_ioc_del_flt_rule *flt_rule;
451 	bool res = true;
452 	int len = 0, cnt = 0;
453         const uint8_t UNIT_RULES = 1;
454 
455 	len = (sizeof(struct ipa_ioc_del_flt_rule)) + (UNIT_RULES * sizeof(struct ipa_flt_rule_del));
456 	flt_rule = (struct ipa_ioc_del_flt_rule *)malloc(len);
457 	if (flt_rule == NULL)
458 	{
459 		IPACMERR("unable to allocate memory for del filter rule\n");
460 		return false;
461 	}
462 
463 	for (cnt = 0; cnt < num_rules; cnt++)
464 	{
465 	    memset(flt_rule, 0, len);
466 	    flt_rule->commit = 1;
467 	    flt_rule->num_hdls = UNIT_RULES;
468 	    flt_rule->ip = ip;
469 
470 	    if (flt_rule_hdls[cnt] == 0)
471 	    {
472 		   IPACMERR("invalid filter handle passed, ignoring it: %d\n", cnt)
473 	    }
474             else
475 	    {
476 
477 		   flt_rule->hdl[0].status = -1;
478 		   flt_rule->hdl[0].hdl = flt_rule_hdls[cnt];
479 		   IPACMDBG("Deleting filter hdl:(0x%x) with ip type: %d\n", flt_rule_hdls[cnt], ip);
480 
481 	           if (DeleteFilteringRule(flt_rule) == false)
482 	           {
483 		        PERROR("Filter rule deletion failed!\n");
484 		        res = false;
485 		        goto fail;
486 	           }
487 		   else
488 	           {
489 
490 		        if (flt_rule->hdl[0].status != 0)
491 		        {
492 			     IPACMERR("Filter rule hdl 0x%x deletion failed with error:%d\n",
493 		        					 flt_rule->hdl[0].hdl, flt_rule->hdl[0].status);
494 			     res = false;
495 			     goto fail;
496 		        }
497 		   }
498 	    }
499 	}
500 
501 fail:
502 	free(flt_rule);
503 
504 	return res;
505 }
506 
AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const * rule_table_v4,struct ipa_ioc_add_flt_rule const * rule_table_v6,uint8_t mux_id)507 bool IPACM_Filtering::AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const *rule_table_v4, struct ipa_ioc_add_flt_rule const * rule_table_v6, uint8_t mux_id)
508 {
509 	int ret = 0, cnt, num_rules = 0, pos = 0;
510 	ipa_install_fltr_rule_req_msg_v01 qmi_rule_msg;
511 	ipa_install_fltr_rule_req_ex_msg_v01 qmi_rule_ex_msg;
512 
513 	memset(&qmi_rule_msg, 0, sizeof(qmi_rule_msg));
514 	int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
515 	if(fd_wwan_ioctl < 0)
516 	{
517 		IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
518 		return false;
519 	}
520 
521 	if(rule_table_v4 != NULL)
522 	{
523 		num_rules += rule_table_v4->num_rules;
524 		IPACMDBG_H("Get %d WAN DL IPv4 filtering rules.\n", rule_table_v4->num_rules);
525 	}
526 	if(rule_table_v6 != NULL)
527 	{
528 		num_rules += rule_table_v6->num_rules;
529 		IPACMDBG_H("Get %d WAN DL IPv6 filtering rules.\n", rule_table_v6->num_rules);
530 	}
531 
532 	/* if it is not IPA v3, use old QMI format */
533 	if (!IPACM_Iface::ipacmcfg->isIPAv3Supported())
534 	{
535 		if(num_rules > QMI_IPA_MAX_FILTERS_V01)
536 		{
537 			IPACMERR("The number of filtering rules exceed limit.\n");
538 			close(fd_wwan_ioctl);
539 			return false;
540 		}
541 		else
542 		{
543 			if (num_rules > 0)
544 			{
545 				qmi_rule_msg.filter_spec_list_valid = true;
546 			}
547 			else
548 			{
549 				qmi_rule_msg.filter_spec_list_valid = false;
550 			}
551 
552 			qmi_rule_msg.filter_spec_list_len = num_rules;
553 			qmi_rule_msg.source_pipe_index_valid = 0;
554 
555 			IPACMDBG_H("Get %d WAN DL filtering rules in total.\n", num_rules);
556 
557 			if(rule_table_v4 != NULL)
558 			{
559 				for(cnt = rule_table_v4->num_rules - 1; cnt >= 0; cnt--)
560 				{
561 					if (pos < QMI_IPA_MAX_FILTERS_V01)
562 					{
563 						qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos;
564 						qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
565 						qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action);
566 						qmi_rule_msg.filter_spec_list[pos].is_routing_table_index_valid = 1;
567 						qmi_rule_msg.filter_spec_list[pos].route_table_index = rule_table_v4->rules[cnt].rule.rt_tbl_idx;
568 						qmi_rule_msg.filter_spec_list[pos].is_mux_id_valid = 1;
569 						qmi_rule_msg.filter_spec_list[pos].mux_id = mux_id;
570 						memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule,
571 							&rule_table_v4->rules[cnt].rule.eq_attrib,
572 							sizeof(struct ipa_filter_rule_type_v01));
573 						pos++;
574 					}
575 					else
576 					{
577 						IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
578 					}
579 				}
580 			}
581 
582 			if(rule_table_v6 != NULL)
583 			{
584 				for(cnt = rule_table_v6->num_rules - 1; cnt >= 0; cnt--)
585 				{
586 					if (pos < QMI_IPA_MAX_FILTERS_V01)
587 					{
588 						qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos;
589 						qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
590 						qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action);
591 						qmi_rule_msg.filter_spec_list[pos].is_routing_table_index_valid = 1;
592 						qmi_rule_msg.filter_spec_list[pos].route_table_index = rule_table_v6->rules[cnt].rule.rt_tbl_idx;
593 						qmi_rule_msg.filter_spec_list[pos].is_mux_id_valid = 1;
594 						qmi_rule_msg.filter_spec_list[pos].mux_id = mux_id;
595 						memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule,
596 							&rule_table_v6->rules[cnt].rule.eq_attrib,
597 							sizeof(struct ipa_filter_rule_type_v01));
598 						pos++;
599 					}
600 					else
601 					{
602 						IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
603 					}
604 				}
605 			}
606 
607 			ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE, &qmi_rule_msg);
608 			if (ret != 0)
609 			{
610 				IPACMERR("Failed adding Filtering rule %p with ret %d\n ", &qmi_rule_msg, ret);
611 				close(fd_wwan_ioctl);
612 				return false;
613 			}
614 		}
615 	/* if it is IPA v3, use new QMI format */
616 	}
617 	else
618 	{
619 		if(num_rules > QMI_IPA_MAX_FILTERS_EX_V01)
620 		{
621 			IPACMERR("The number of filtering rules exceed limit.\n");
622 			close(fd_wwan_ioctl);
623 			return false;
624 		}
625 		else
626 		{
627 			memset(&qmi_rule_ex_msg, 0, sizeof(qmi_rule_ex_msg));
628 
629 			if (num_rules > 0)
630 			{
631 				qmi_rule_ex_msg.filter_spec_ex_list_valid = true;
632 			}
633 			else
634 			{
635 				qmi_rule_ex_msg.filter_spec_ex_list_valid = false;
636 			}
637 			qmi_rule_ex_msg.filter_spec_ex_list_len = num_rules;
638 			qmi_rule_ex_msg.source_pipe_index_valid = 0;
639 
640 			IPACMDBG_H("Get %d WAN DL filtering rules in total.\n", num_rules);
641 
642 			if(rule_table_v4 != NULL)
643 			{
644 				for(cnt = rule_table_v4->num_rules - 1; cnt >= 0; cnt--)
645 				{
646 					if (pos < QMI_IPA_MAX_FILTERS_EX_V01)
647 					{
648 						qmi_rule_ex_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
649 						qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action);
650 						qmi_rule_ex_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
651 						qmi_rule_ex_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v4->rules[cnt].rule.rt_tbl_idx;
652 						qmi_rule_ex_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
653 						qmi_rule_ex_msg.filter_spec_ex_list[pos].mux_id = mux_id;
654 						qmi_rule_ex_msg.filter_spec_ex_list[pos].rule_id = rule_table_v4->rules[cnt].rule.rule_id;
655 						qmi_rule_ex_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v4->rules[cnt].rule.hashable;
656 						memcpy(&qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_rule,
657 							&rule_table_v4->rules[cnt].rule.eq_attrib,
658 							sizeof(struct ipa_filter_rule_type_v01));
659 
660 						pos++;
661 					}
662 					else
663 					{
664 						IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_EX_V01, pos);
665 					}
666 				}
667 			}
668 
669 			if(rule_table_v6 != NULL)
670 			{
671 				for(cnt = rule_table_v6->num_rules - 1; cnt >= 0; cnt--)
672 				{
673 					if (pos < QMI_IPA_MAX_FILTERS_EX_V01)
674 					{
675 						qmi_rule_ex_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
676 						qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action);
677 						qmi_rule_ex_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
678 						qmi_rule_ex_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v6->rules[cnt].rule.rt_tbl_idx;
679 						qmi_rule_ex_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
680 						qmi_rule_ex_msg.filter_spec_ex_list[pos].mux_id = mux_id;
681 						qmi_rule_ex_msg.filter_spec_ex_list[pos].rule_id = rule_table_v6->rules[cnt].rule.rule_id;
682 						qmi_rule_ex_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v6->rules[cnt].rule.hashable;
683 						memcpy(&qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_rule,
684 							&rule_table_v6->rules[cnt].rule.eq_attrib,
685 							sizeof(struct ipa_filter_rule_type_v01));
686 
687 						pos++;
688 					}
689 					else
690 					{
691 						IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_EX_V01, pos);
692 					}
693 				}
694 			}
695 
696 			ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE_EX, &qmi_rule_ex_msg);
697 			if (ret != 0)
698 			{
699 				IPACMERR("Failed adding Filtering rule %pK with ret %d\n ", &qmi_rule_ex_msg, ret);
700 				close(fd_wwan_ioctl);
701 				return false;
702 			}
703 		}
704 	}
705 
706 	close(fd_wwan_ioctl);
707 	return true;
708 }
709 
AddOffloadFilteringRule(struct ipa_ioc_add_flt_rule * flt_rule_tbl,uint8_t mux_id,uint8_t default_path)710 bool IPACM_Filtering::AddOffloadFilteringRule(struct ipa_ioc_add_flt_rule *flt_rule_tbl, uint8_t mux_id, uint8_t default_path)
711 {
712 #ifdef WAN_IOCTL_ADD_OFFLOAD_CONNECTION
713 	int ret = 0, cnt, pos = 0;
714 	ipa_add_offload_connection_req_msg_v01 qmi_add_msg;
715 	int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
716 	if(fd_wwan_ioctl < 0)
717 	{
718 		IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
719 		return false;
720 	}
721 
722 	if(flt_rule_tbl == NULL)
723 	{
724 		if(mux_id ==0)
725 		{
726 			IPACMERR("Invalid add_offload_req muxd: (%d)\n", mux_id);
727 			close(fd_wwan_ioctl);
728 			return false;
729 		}
730 #ifdef QMI_IPA_MAX_FILTERS_EX2_V01
731 		/* used for sending mux_id info to modem for UL sky*/
732 		IPACMDBG_H("sending mux_id info (%d) to modem for UL\n", mux_id);
733 		memset(&qmi_add_msg, 0, sizeof(qmi_add_msg));
734 		qmi_add_msg.embedded_call_mux_id_valid = true;
735 		qmi_add_msg.embedded_call_mux_id = mux_id;
736 		ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_OFFLOAD_CONNECTION, &qmi_add_msg);
737 		if (ret != 0)
738 		{
739 			IPACMERR("Failed sending WAN_IOC_ADD_OFFLOAD_CONNECTION with ret %d\n ", ret);
740 			close(fd_wwan_ioctl);
741 			return false;
742 		}
743 #endif
744 		close(fd_wwan_ioctl);
745 		return true;
746 	}
747 	/* check Max offload connections */
748 	if (total_num_offload_rules + flt_rule_tbl->num_rules > QMI_IPA_MAX_FILTERS_V01)
749 	{
750 		IPACMERR("(%d) add_offload req with curent(%d), exceed max (%d).\n",
751 		flt_rule_tbl->num_rules, total_num_offload_rules,
752 		QMI_IPA_MAX_FILTERS_V01);
753 		close(fd_wwan_ioctl);
754 		return false;
755 	}
756 	else
757 	{
758 		memset(&qmi_add_msg, 0, sizeof(qmi_add_msg));
759 
760 		if (flt_rule_tbl->num_rules > 0)
761 		{
762 			qmi_add_msg.filter_spec_ex2_list_valid = true;
763 		}
764 		else
765 		{
766 			IPACMDBG_H("Get %d offload-req\n", flt_rule_tbl->num_rules);
767 			close(fd_wwan_ioctl);
768 			return true;
769 		}
770 		qmi_add_msg.filter_spec_ex2_list_len = flt_rule_tbl->num_rules;
771 
772 		/* check if we want to take default MHI path */
773 		if (default_path)
774 		{
775 			qmi_add_msg.default_mhi_path_valid = true;
776 			qmi_add_msg.default_mhi_path = true;
777 		}
778 
779 		IPACMDBG_H("passing %d offload req to modem. default %d\n", flt_rule_tbl->num_rules, qmi_add_msg.default_mhi_path);
780 
781 		if(flt_rule_tbl != NULL)
782 		{
783 			for(cnt = flt_rule_tbl->num_rules - 1; cnt >= 0; cnt--)
784 			{
785 				if (pos < QMI_IPA_MAX_FILTERS_V01)
786 				{
787 					if (flt_rule_tbl->ip == IPA_IP_v4)
788 					{
789 						qmi_add_msg.filter_spec_ex2_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
790 					} else if (flt_rule_tbl->ip == IPA_IP_v6) {
791 						qmi_add_msg.filter_spec_ex2_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
792 					} else {
793 						IPACMDBG_H("invalid ip-type %d\n", flt_rule_tbl->ip);
794 						close(fd_wwan_ioctl);
795 						return true;
796 					}
797 
798 					qmi_add_msg.filter_spec_ex2_list[pos].filter_action = GetQmiFilterAction(flt_rule_tbl->rules[cnt].rule.action);
799 					qmi_add_msg.filter_spec_ex2_list[pos].is_mux_id_valid = 1;
800 					qmi_add_msg.filter_spec_ex2_list[pos].mux_id = mux_id;
801 					/* assign the rule-id */
802 					flt_rule_tbl->rules[cnt].flt_rule_hdl = IPA_PCIE_MODEM_RULE_ID_START + pcie_modem_rule_id;
803 					qmi_add_msg.filter_spec_ex2_list[pos].rule_id = flt_rule_tbl->rules[cnt].flt_rule_hdl;
804 					qmi_add_msg.filter_spec_ex2_list[pos].is_rule_hashable = flt_rule_tbl->rules[cnt].rule.hashable;
805 					memcpy(&qmi_add_msg.filter_spec_ex2_list[pos].filter_rule,
806 						&flt_rule_tbl->rules[cnt].rule.eq_attrib,
807 						sizeof(struct ipa_filter_rule_type_v01));
808 					IPACMDBG_H("mux-id %d, hashable %d\n", qmi_add_msg.filter_spec_ex2_list[pos].mux_id, qmi_add_msg.filter_spec_ex2_list[pos].is_rule_hashable);
809 					pos++;
810 					pcie_modem_rule_id = (pcie_modem_rule_id + 1)%100;
811 				}
812 				else
813 				{
814 					IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
815 				}
816 			}
817 		}
818 
819 		ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_OFFLOAD_CONNECTION, &qmi_add_msg);
820 		if (ret != 0)
821 		{
822 			IPACMERR("Failed sending WAN_IOC_ADD_OFFLOAD_CONNECTION with ret %d\n ", ret);
823 			close(fd_wwan_ioctl);
824 			return false;
825 		}
826 	}
827 	/* update total_num_offload_rules */
828 	total_num_offload_rules += flt_rule_tbl->num_rules;
829 	IPACMDBG_H("total_num_offload_rules %d \n", total_num_offload_rules);
830 	close(fd_wwan_ioctl);
831 	return true;
832 #else
833 	if(flt_rule_tbl != NULL)
834 	{
835 		IPACMERR("Not support (%d) AddOffloadFilteringRule with mux-id (%d) and default path = %d\n", flt_rule_tbl->num_rules, mux_id, default_path);
836 	}
837 	return false;
838 #endif
839 }
840 
DelOffloadFilteringRule(struct ipa_ioc_del_flt_rule const * flt_rule_tbl)841 bool IPACM_Filtering::DelOffloadFilteringRule(struct ipa_ioc_del_flt_rule const *flt_rule_tbl)
842 {
843 #ifdef WAN_IOCTL_ADD_OFFLOAD_CONNECTION
844 	bool result = true;
845 	int ret = 0, cnt, pos = 0;
846 	ipa_remove_offload_connection_req_msg_v01 qmi_del_msg;
847 	int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
848 
849 	if(fd_wwan_ioctl < 0)
850 	{
851 		IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
852 		return false;
853 	}
854 
855 	if(flt_rule_tbl == NULL)
856 	{
857 		IPACMERR("Invalid add_offload_req\n");
858 		result =  false;
859 		goto fail;
860 	}
861 
862 	/* check # of offload connections */
863 	if (flt_rule_tbl->num_hdls > total_num_offload_rules) {
864 		IPACMERR("(%d) del_offload req , exceed curent(%d)\n",
865 		flt_rule_tbl->num_hdls, total_num_offload_rules);
866 		result =  false;
867 		goto fail;
868 	}
869 	else
870 	{
871 		memset(&qmi_del_msg, 0, sizeof(qmi_del_msg));
872 
873 		if (flt_rule_tbl->num_hdls > 0)
874 		{
875 			qmi_del_msg.filter_handle_list_valid = true;
876 		}
877 		else
878 		{
879 			IPACMERR("Get %d offload-req\n", flt_rule_tbl->num_hdls);
880 			goto fail;
881 		}
882 		qmi_del_msg.filter_handle_list_len = flt_rule_tbl->num_hdls;
883 
884 		IPACMDBG_H("passing %d offload req to modem.\n", flt_rule_tbl->num_hdls);
885 
886 		if(flt_rule_tbl != NULL)
887 		{
888 			for(cnt = flt_rule_tbl->num_hdls - 1; cnt >= 0; cnt--)
889 			{
890 				if (pos < QMI_IPA_MAX_FILTERS_V01)
891 				{
892 					/* passing rule-id to wan-driver */
893 					qmi_del_msg.filter_handle_list[pos].filter_spec_identifier = flt_rule_tbl->hdl[cnt].hdl;
894 					pos++;
895 				}
896 				else
897 				{
898 					IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
899 					result =  false;
900 					goto fail;
901 				}
902 			}
903 		}
904 
905 		ret = ioctl(fd_wwan_ioctl, WAN_IOC_RMV_OFFLOAD_CONNECTION, &qmi_del_msg);
906 		if (ret != 0)
907 		{
908 			IPACMERR("Failed deleting Filtering rule %pK with ret %d\n ", &qmi_del_msg, ret);
909 			result =  false;
910 			goto fail;
911 		}
912 	}
913 	/* update total_num_offload_rules */
914 	total_num_offload_rules -= flt_rule_tbl->num_hdls;
915 	IPACMDBG_H("total_num_offload_rules %d \n", total_num_offload_rules);
916 
917 fail:
918 	close(fd_wwan_ioctl);
919 	return result;
920 #else
921 	if(flt_rule_tbl != NULL)
922 	{
923 		IPACMERR("Not support (%d) DelOffloadFilteringRule\n", flt_rule_tbl->num_hdls);
924 	}
925 	return false;
926 #endif
927 }
928 
SendFilteringRuleIndex(struct ipa_fltr_installed_notif_req_msg_v01 * table)929 bool IPACM_Filtering::SendFilteringRuleIndex(struct ipa_fltr_installed_notif_req_msg_v01* table)
930 {
931 	int ret = 0;
932 	int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
933 	if(fd_wwan_ioctl < 0)
934 	{
935 		IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
936 		return false;
937 	}
938 
939 	ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE_INDEX, table);
940 	if (ret != 0)
941 	{
942 		IPACMERR("Failed adding filtering rule index %pK with ret %d\n", table, ret);
943 		close(fd_wwan_ioctl);
944 		return false;
945 	}
946 
947 	IPACMDBG("Added Filtering rule index %pK\n", table);
948 	close(fd_wwan_ioctl);
949 	return true;
950 }
951 
GetQmiFilterAction(ipa_flt_action action)952 ipa_filter_action_enum_v01 IPACM_Filtering::GetQmiFilterAction(ipa_flt_action action)
953 {
954 	switch(action)
955 	{
956 	case IPA_PASS_TO_ROUTING:
957 		return QMI_IPA_FILTER_ACTION_ROUTING_V01;
958 
959 	case IPA_PASS_TO_SRC_NAT:
960 		return QMI_IPA_FILTER_ACTION_SRC_NAT_V01;
961 
962 	case IPA_PASS_TO_DST_NAT:
963 		return QMI_IPA_FILTER_ACTION_DST_NAT_V01;
964 
965 	case IPA_PASS_TO_EXCEPTION:
966 		return QMI_IPA_FILTER_ACTION_EXCEPTION_V01;
967 
968 	default:
969 		return IPA_FILTER_ACTION_ENUM_MAX_ENUM_VAL_V01;
970 	}
971 }
972 
ModifyFilteringRule(struct ipa_ioc_mdfy_flt_rule * ruleTable)973 bool IPACM_Filtering::ModifyFilteringRule(struct ipa_ioc_mdfy_flt_rule* ruleTable)
974 {
975 	int i, ret = 0;
976 
977 	IPACMDBG("Printing filtering add attributes\n");
978 	IPACMDBG("IP type: %d Number of rules: %d commit value: %d\n", ruleTable->ip, ruleTable->num_rules, ruleTable->commit);
979 
980 	for (i=0; i<ruleTable->num_rules; i++)
981 	{
982 		IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", i, ruleTable->rules[i].rule.attrib.attrib_mask);
983 	}
984 
985 	ret = ioctl(fd, IPA_IOC_MDFY_FLT_RULE, ruleTable);
986 	if (ret != 0)
987 	{
988 		IPACMERR("Failed modifying filtering rule %pK\n", ruleTable);
989 
990 		for (i = 0; i < ruleTable->num_rules; i++)
991 		{
992 			if (ruleTable->rules[i].status != 0)
993 			{
994 				IPACMERR("Modifying filter rule %d failed\n", i);
995 			}
996 		}
997 		return false;
998 	}
999 
1000 	IPACMDBG("Modified filtering rule %p\n", ruleTable);
1001 	return true;
1002 }
1003 
1004