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