• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright (c) 2013-2016, 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_Config.h
32 
33 	@brief
34 	This file implements the IPACM Configuration from XML file
35 
36 	@Author
37 	Skylar Chang
38 
39 */
40 #ifndef IPACM_CONFIG_H
41 #define IPACM_CONFIG_H
42 
43 #include "IPACM_Defs.h"
44 #include "IPACM_Xml.h"
45 #include "IPACM_EvtDispatcher.h"
46 
47 typedef struct
48 {
49   char iface_name[IPA_IFACE_NAME_LEN];
50 }NatIfaces;
51 
52 /* for IPACM rm dependency use*/
53 typedef struct _ipa_rm_client
54 {
55     ipa_rm_resource_name producer_rm1;
56     ipa_rm_resource_name consumer_rm1;
57     ipa_rm_resource_name producer_rm2;
58     ipa_rm_resource_name consumer_rm2;
59     bool producer1_up;            /* only monitor producer_rm1, not monitor producer_rm2 */
60     bool consumer1_up;            /* only monitor consumer_rm1, not monitor consumer_rm2 */
61     bool rm_set;                  /* once producer1_up and consumer1_up, will add bi-directional dependency */
62     bool rx_bypass_ipa;          /* support WLAN may not register RX-property, should not add dependency */
63 }ipa_rm_client;
64 
65 #define MAX_NUM_EXT_PROPS 25
66 
67 /* used to hold extended properties */
68 typedef struct
69 {
70 	uint8_t num_ext_props;
71 	ipa_ioc_ext_intf_prop prop[MAX_NUM_EXT_PROPS];
72 } ipacm_ext_prop;
73 
74 /* iface */
75 class IPACM_Config
76 {
77 public:
78 
79 	/* IPACM ipa_client map to rm_resource*/
80 	ipa_rm_resource_name ipa_client_rm_map_tbl[IPA_CLIENT_MAX];
81 
82 	/* IPACM monitored rm_depency table */
83 	ipa_rm_client ipa_rm_tbl[IPA_MAX_RM_ENTRY];
84 
85 	/* IPACM rm_depency a2 endpoint check*/
86 	int ipa_rm_a2_check;
87 
88 	/* Store interested interface and their configuration from XML file */
89 	ipa_ifi_dev_name_t *iface_table;
90 
91 	/* Store interested ALG port from XML file */
92 	ipacm_alg *alg_table;
93 
94 	/* Store private subnet configuration from XML file */
95 	ipa_private_subnet private_subnet_table[IPA_MAX_PRIVATE_SUBNET_ENTRIES];
96 
97 	/* Store the non nat iface names */
98 	NatIfaces *pNatIfaces;
99 
100 	/* Store the bridge iface names */
101 	char ipa_virtual_iface_name[IPA_IFACE_NAME_LEN];
102 
103 	/* Store the number of interface IPACM read from XML file */
104 	int ipa_num_ipa_interfaces;
105 
106 	int ipa_num_private_subnet;
107 
108 	int ipa_num_alg_ports;
109 
110 	int ipa_nat_max_entries;
111 
112 	bool ipacm_odu_router_mode;
113 
114 	bool ipacm_odu_enable;
115 
116 	bool ipacm_odu_embms_enable;
117 
118 	bool ipacm_ip_passthrough_mode;
119 
120 	int ipa_nat_iface_entries;
121 
122 	/* Store the total number of wlan guest ap configured */
123 	int ipa_num_wlan_guest_ap;
124 
125 	/* Max valid rm entry */
126 	int ipa_max_valid_rm_entry;
127 
128 	/* Store SW-enable or not */
129 	bool ipa_sw_rt_enable;
130 
131 	/* Store bridge mode or not */
132 	bool ipa_bridge_enable;
133 
134 	/* Store bridge netdev mac */
135 	uint8_t bridge_mac[IPA_MAC_ADDR_SIZE];
136 
137 	/* Store the flt rule count for each producer client*/
138 	int flt_rule_count_v4[IPA_CLIENT_CONS - IPA_CLIENT_PROD];
139 	int flt_rule_count_v6[IPA_CLIENT_CONS - IPA_CLIENT_PROD];
140 
141 	/* IPACM routing table name for v4/v6 */
142 	struct ipa_ioc_get_rt_tbl rt_tbl_lan_v4, rt_tbl_wan_v4, rt_tbl_default_v4, rt_tbl_v6, rt_tbl_wan_v6;
143 	struct ipa_ioc_get_rt_tbl rt_tbl_wan_dl;
144 	struct ipa_ioc_get_rt_tbl rt_tbl_odu_v4, rt_tbl_odu_v6;
145 
146 	bool isMCC_Mode;
147 
148 	/* To return the instance */
149 	static IPACM_Config* GetInstance();
150 
151 	const char* getEventName(ipa_cm_event_id event_id);
152 
increaseFltRuleCount(int index,ipa_ip_type iptype,int increment)153 	inline void increaseFltRuleCount(int index, ipa_ip_type iptype, int increment)
154 	{
155 		if((index >= IPA_CLIENT_CONS - IPA_CLIENT_PROD) || (index < 0))
156 		{
157 			IPACMERR("Index is out of range: %d.\n", index);
158 			return;
159 		}
160 		if(iptype == IPA_IP_v4)
161 		{
162 			flt_rule_count_v4[index] += increment;
163 			IPACMDBG_H("Now num of v4 flt rules on client %d is %d.\n", index, flt_rule_count_v4[index]);
164 		}
165 		else
166 		{
167 			flt_rule_count_v6[index] += increment;
168 			IPACMDBG_H("Now num of v6 flt rules on client %d is %d.\n", index, flt_rule_count_v6[index]);
169 		}
170 		return;
171 	}
172 
decreaseFltRuleCount(int index,ipa_ip_type iptype,int decrement)173 	inline void decreaseFltRuleCount(int index, ipa_ip_type iptype, int decrement)
174 	{
175 		if((index >= IPA_CLIENT_CONS - IPA_CLIENT_PROD) || (index < 0))
176 		{
177 			IPACMERR("Index is out of range: %d.\n", index);
178 			return;
179 		}
180 		if(iptype == IPA_IP_v4)
181 		{
182 			flt_rule_count_v4[index] -= decrement;
183 			IPACMDBG_H("Now num of v4 flt rules on client %d is %d.\n", index, flt_rule_count_v4[index]);
184 		}
185 		else
186 		{
187 			flt_rule_count_v6[index] -= decrement;
188 			IPACMDBG_H("Now num of v6 flt rules on client %d is %d.\n", index, flt_rule_count_v6[index]);
189 		}
190 		return;
191 	}
192 
getFltRuleCount(int index,ipa_ip_type iptype)193 	inline int getFltRuleCount(int index, ipa_ip_type iptype)
194 	{
195 		if((index >= IPA_CLIENT_CONS - IPA_CLIENT_PROD) || (index < 0))
196 		{
197 			IPACMERR("Index is out of range: %d.\n", index);
198 			return -1;
199 		}
200 		if(iptype == IPA_IP_v4)
201 		{
202 			return flt_rule_count_v4[index];
203 		}
204 		else
205 		{
206 			return flt_rule_count_v6[index];
207 		}
208 	}
209 
GetAlgPortCnt()210 	inline int GetAlgPortCnt()
211 	{
212 		return ipa_num_alg_ports;
213 	}
214 
215 	int GetAlgPorts(int nPorts, ipacm_alg *pAlgPorts);
216 
GetNatMaxEntries(void)217 	inline int GetNatMaxEntries(void)
218 	{
219 		return ipa_nat_max_entries;
220 	}
221 
GetNatIfacesCnt()222 	inline int GetNatIfacesCnt()
223 	{
224 		return ipa_nat_iface_entries;
225 	}
226 	int GetNatIfaces(int nPorts, NatIfaces *ifaces);
227 
228 	/* for IPACM resource manager dependency usage */
229 	void AddRmDepend(ipa_rm_resource_name rm1,bool rx_bypass_ipa);
230 
231 	void DelRmDepend(ipa_rm_resource_name rm1);
232 
233 	int AddNatIfaces(char *dev_name);
234 
235 	int DelNatIfaces(char *dev_name);
236 
237 	int CheckNatIfaces(const char *dev_name);
238 
SetQmapId(uint8_t id)239 	inline void SetQmapId(uint8_t id)
240 	{
241 		qmap_id = id;
242 	}
243 
GetQmapId()244 	inline uint8_t GetQmapId()
245 	{
246 		return qmap_id;
247 	}
248 
249 	int SetExtProp(ipa_ioc_query_intf_ext_props *prop);
250 
251 	ipacm_ext_prop* GetExtProp(ipa_ip_type ip_type);
252 
253 	int DelExtProp(ipa_ip_type ip_type);
254 
255 	int Init(void);
256 
isPrivateSubnet(uint32_t ip_addr)257 	inline bool isPrivateSubnet(uint32_t ip_addr)
258 	{
259 		for(int cnt=0; cnt<ipa_num_private_subnet; cnt++)
260 		{
261 			if(private_subnet_table[cnt].subnet_addr ==
262 				 (private_subnet_table[cnt].subnet_mask & ip_addr))
263 			{
264 				return true;
265 			}
266 		}
267 
268 		return false;
269 	}
270 #ifdef FEATURE_IPA_ANDROID
AddPrivateSubnet(uint32_t ip_addr,int ipa_if_index)271 	inline bool AddPrivateSubnet(uint32_t ip_addr, int ipa_if_index)
272 	{
273 		ipacm_cmd_q_data evt_data;
274 		ipacm_event_data_fid *data_fid;
275 		uint32_t subnet_mask = ~0;
276 		for(int cnt=0; cnt<ipa_num_private_subnet; cnt++)
277 		{
278 			if(private_subnet_table[cnt].subnet_addr == ip_addr)
279 			{
280 				IPACMDBG("Already has private subnet_addr as: 0x%x in entry(%d) \n", ip_addr, cnt);
281 				return true;
282 			}
283 		}
284 
285 		if(ipa_num_private_subnet < IPA_MAX_PRIVATE_SUBNET_ENTRIES)
286 		{
287 			IPACMDBG("Add IPACM private subnet_addr as: 0x%x in entry(%d) \n", ip_addr, ipa_num_private_subnet);
288 			private_subnet_table[ipa_num_private_subnet].subnet_addr = ip_addr;
289 			private_subnet_table[ipa_num_private_subnet].subnet_mask = (subnet_mask >> 8) << 8;
290 			ipa_num_private_subnet++;
291 
292 			/* IPACM private subnet set changes */
293 			data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
294 			if(data_fid == NULL)
295 			{
296 				IPACMERR("unable to allocate memory for event data_fid\n");
297 				return IPACM_FAILURE;
298 			}
299 			data_fid->if_index = ipa_if_index; // already ipa index, not fid index
300 			evt_data.event = IPA_PRIVATE_SUBNET_CHANGE_EVENT;
301 			evt_data.evt_data = data_fid;
302 
303 			/* Insert IPA_PRIVATE_SUBNET_CHANGE_EVENT to command queue */
304 			IPACM_EvtDispatcher::PostEvt(&evt_data);
305 			return true;
306 		}
307 		IPACMERR("IPACM private subnet_addr overflow, total entry(%d)\n", ipa_num_private_subnet);
308 		return false;
309 	}
310 
DelPrivateSubnet(uint32_t ip_addr,int ipa_if_index)311 	inline bool DelPrivateSubnet(uint32_t ip_addr, int ipa_if_index)
312 	{
313 		ipacm_cmd_q_data evt_data;
314 		ipacm_event_data_fid *data_fid;
315 		for(int cnt=0; cnt<ipa_num_private_subnet; cnt++)
316 		{
317 			if(private_subnet_table[cnt].subnet_addr == ip_addr)
318 			{
319 				IPACMDBG("Found private subnet_addr as: 0x%x in entry(%d) \n", ip_addr, cnt);
320 				for (; cnt < ipa_num_private_subnet - 1; cnt++)
321 				{
322 					private_subnet_table[cnt].subnet_addr = private_subnet_table[cnt+1].subnet_addr;
323 				}
324 				ipa_num_private_subnet = ipa_num_private_subnet - 1;
325 
326 				/* IPACM private subnet set changes */
327 				data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
328 				if(data_fid == NULL)
329 				{
330 					IPACMERR("unable to allocate memory for event data_fid\n");
331 					return IPACM_FAILURE;
332 				}
333 				data_fid->if_index = ipa_if_index; // already ipa index, not fid index
334 				evt_data.event = IPA_PRIVATE_SUBNET_CHANGE_EVENT;
335 				evt_data.evt_data = data_fid;
336 
337 				/* Insert IPA_PRIVATE_SUBNET_CHANGE_EVENT to command queue */
338 				IPACM_EvtDispatcher::PostEvt(&evt_data);
339 				return true;
340 			}
341 		}
342 		IPACMDBG("can't find private subnet_addr as: 0x%x \n", ip_addr);
343 		return false;
344 	}
345 #endif /* defined(FEATURE_IPA_ANDROID)*/
346 
347 	static const char *DEVICE_NAME_ODU;
348 
349 private:
350 	static IPACM_Config *pInstance;
351 	static const char *DEVICE_NAME;
352 	IPACM_Config(void);
353 	int m_fd; /* File descriptor of the IPA device node /dev/ipa */
354 	uint8_t qmap_id;
355 	ipacm_ext_prop ext_prop_v4;
356 	ipacm_ext_prop ext_prop_v6;
357 };
358 
359 #endif /* IPACM_CONFIG */
360