blob: ec704b26240c2c91b26a9c52f728e0bf45836174 [file] [log] [blame]
Nicolas Costaf46c33b2014-05-15 10:02:00 -05001/*
2 **************************************************************************
3 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all copies.
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 **************************************************************************
15 */
16#include <linux/module.h>
Murat Sezginf2b94532014-12-05 14:53:53 -080017#include <linux/of.h>
Nicolas Costaf46c33b2014-05-15 10:02:00 -050018
19extern int ecm_tracker_init(void);
20extern void ecm_tracker_exit(void);
21
22extern int ecm_db_init(void);
23extern void ecm_db_connection_defunct_all(void);
24extern void ecm_db_exit(void);
25
26extern int ecm_tracker_tcp_module_init(void);
27extern void ecm_tracker_tcp_module_exit(void);
28
29extern int ecm_tracker_udp_module_init(void);
30extern void ecm_tracker_udp_module_exit(void);
31
32extern int ecm_tracker_datagram_module_init(void);
33extern void ecm_tracker_datagram_module_exit(void);
34
35extern int ecm_classifier_default_init(void);
36extern void ecm_classifier_default_exit(void);
37
Murat Sezginaaaafb42014-11-24 17:02:05 -080038#ifdef ECM_CLASSIFIER_NL_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -050039extern int ecm_classifier_nl_rules_init(void);
40extern void ecm_classifier_nl_rules_exit(void);
Murat Sezginaaaafb42014-11-24 17:02:05 -080041#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -050042
Hai Shalom81f4e202014-06-04 09:30:27 -070043#ifdef ECM_CLASSIFIER_HYFI_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -050044extern int ecm_classifier_hyfi_rules_init(void);
45extern void ecm_classifier_hyfi_rules_exit(void);
Hai Shalom81f4e202014-06-04 09:30:27 -070046#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -050047
48extern int ecm_interface_init(void);
49extern void ecm_interface_stop(int);
50extern void ecm_interface_exit(void);
51
Murat Sezginb3731e82014-11-26 12:20:59 -080052#ifdef ECM_INTERFACE_BOND_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -050053extern int ecm_bond_notifier_init(void);
54extern void ecm_bond_notifier_stop(int);
55extern void ecm_bond_notifier_exit(void);
Murat Sezginb3731e82014-11-26 12:20:59 -080056#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -050057
58extern int ecm_front_end_ipv4_init(void);
59extern void ecm_front_end_ipv4_stop(int);
60extern void ecm_front_end_ipv4_exit(void);
61
Murat Sezgin49465a42014-11-24 15:37:48 -080062#ifdef ECM_FRONT_END_IPV6_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -050063extern int ecm_front_end_ipv6_init(void);
64extern void ecm_front_end_ipv6_stop(int);
65extern void ecm_front_end_ipv6_exit(void);
Murat Sezgin49465a42014-11-24 15:37:48 -080066#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -050067
68extern int ecm_conntrack_notifier_init(void);
69extern void ecm_conntrack_notifier_stop(int);
70extern void ecm_conntrack_notifier_exit(void);
71
Murat Sezginb3731e82014-11-26 12:20:59 -080072#ifdef ECM_CLASSIFIER_DSCP_ENABLE
Gareth Williams4a02c9b2014-10-10 14:50:33 +010073extern int ecm_classifier_dscp_init(void);
74extern void ecm_classifier_dscp_exit(void);
Murat Sezginb3731e82014-11-26 12:20:59 -080075#endif
Gareth Williams4a02c9b2014-10-10 14:50:33 +010076
Nicolas Costaf46c33b2014-05-15 10:02:00 -050077/*
78 * ecm_init()
79 */
80static int __init ecm_init(void)
81{
82 int ret;
Murat Sezginf2b94532014-12-05 14:53:53 -080083
84 /*
85 * Run only for IPQ8064 platform, if the device tree is used.
86 */
87#ifdef CONFIG_OF
88 if (!of_machine_is_compatible("qcom,ipq8064")) {
89 printk(KERN_WARNING "Not compatible platform for ECM\n");
90 return 0;
91 }
92#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -050093 printk(KERN_INFO "ECM init\n");
94
95 ret = ecm_tracker_init();
96 if (0 != ret) {
97 return ret;
98 }
99
100 ret = ecm_db_init();
101 if (0 != ret) {
102 goto err_db;
103 }
104
105 ret = ecm_tracker_tcp_module_init();
106 if (0 != ret) {
107 goto err_tr_tcp;
108 }
109
110 ret = ecm_tracker_udp_module_init();
111 if (0 != ret) {
112 goto err_tr_udp;
113 }
114
115 ret = ecm_tracker_datagram_module_init();
116 if (0 != ret) {
117 goto err_tr_datagram;
118 }
119
120 ret = ecm_classifier_default_init();
121 if (0 != ret) {
122 goto err_cls_default;
123 }
124
Murat Sezginaaaafb42014-11-24 17:02:05 -0800125#ifdef ECM_CLASSIFIER_NL_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500126 ret = ecm_classifier_nl_rules_init();
127 if (0 != ret) {
128 goto err_cls_nl;
129 }
Murat Sezginaaaafb42014-11-24 17:02:05 -0800130#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500131
Hai Shalom81f4e202014-06-04 09:30:27 -0700132#ifdef ECM_CLASSIFIER_HYFI_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500133 ret = ecm_classifier_hyfi_rules_init();
134 if (0 != ret) {
135 goto err_cls_hyfi;
136 }
Hai Shalom81f4e202014-06-04 09:30:27 -0700137#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500138
Murat Sezginb3731e82014-11-26 12:20:59 -0800139#ifdef ECM_CLASSIFIER_DSCP_ENABLE
Gareth Williams4a02c9b2014-10-10 14:50:33 +0100140 ret = ecm_classifier_dscp_init();
141 if (0 != ret) {
142 goto err_cls_dscp;
143 }
Murat Sezginb3731e82014-11-26 12:20:59 -0800144#endif
Gareth Williams4a02c9b2014-10-10 14:50:33 +0100145
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500146 ret = ecm_interface_init();
147 if (0 != ret) {
148 goto err_iface;
149 }
150
Murat Sezginb3731e82014-11-26 12:20:59 -0800151#ifdef ECM_INTERFACE_BOND_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500152 ret = ecm_bond_notifier_init();
153 if (0 != ret) {
154 goto err_bond;
155 }
Murat Sezginb3731e82014-11-26 12:20:59 -0800156#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500157
158 ret = ecm_front_end_ipv4_init();
159 if (0 != ret) {
160 goto err_fe_ipv4;
161 }
162
Murat Sezgin49465a42014-11-24 15:37:48 -0800163#ifdef ECM_FRONT_END_IPV6_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500164 ret = ecm_front_end_ipv6_init();
165 if (0 != ret) {
166 goto err_fe_ipv6;
167 }
Murat Sezgin49465a42014-11-24 15:37:48 -0800168#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500169
170 ret = ecm_conntrack_notifier_init();
171 if (0 != ret) {
172 goto err_ct;
173 }
174
175 printk(KERN_INFO "ECM init complete\n");
176 return 0;
177
178err_ct:
Murat Sezgin49465a42014-11-24 15:37:48 -0800179#ifdef ECM_FRONT_END_IPV6_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500180 ecm_front_end_ipv6_exit();
181err_fe_ipv6:
Murat Sezgin49465a42014-11-24 15:37:48 -0800182#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500183 ecm_front_end_ipv4_exit();
184err_fe_ipv4:
Murat Sezginb3731e82014-11-26 12:20:59 -0800185#ifdef ECM_INTERFACE_BOND_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500186 ecm_bond_notifier_exit();
187err_bond:
Murat Sezginb3731e82014-11-26 12:20:59 -0800188#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500189 ecm_interface_exit();
190err_iface:
Murat Sezginb3731e82014-11-26 12:20:59 -0800191#ifdef ECM_CLASSIFIER_DSCP_ENABLE
Gareth Williams4a02c9b2014-10-10 14:50:33 +0100192 ecm_classifier_dscp_exit();
193err_cls_dscp:
Murat Sezginb3731e82014-11-26 12:20:59 -0800194#endif
Hai Shalom81f4e202014-06-04 09:30:27 -0700195#ifdef ECM_CLASSIFIER_HYFI_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500196 ecm_classifier_hyfi_rules_exit();
197err_cls_hyfi:
Hai Shalom81f4e202014-06-04 09:30:27 -0700198#endif
Murat Sezginaaaafb42014-11-24 17:02:05 -0800199#ifdef ECM_CLASSIFIER_NL_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500200 ecm_classifier_nl_rules_exit();
201err_cls_nl:
Murat Sezginaaaafb42014-11-24 17:02:05 -0800202#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500203 ecm_classifier_default_exit();
204err_cls_default:
205 ecm_tracker_datagram_module_exit();
206err_tr_datagram:
207 ecm_tracker_udp_module_exit();
208err_tr_udp:
209 ecm_tracker_tcp_module_exit();
210err_tr_tcp:
211 ecm_db_exit();
212err_db:
213 ecm_tracker_exit();
214
215 printk(KERN_INFO "ECM init failed: %d\n", ret);
216 return ret;
217}
218
219/*
220 * ecm_exit()
221 */
222static void __exit ecm_exit(void)
223{
224 printk(KERN_INFO "ECM exit\n");
225
Murat Sezginf2b94532014-12-05 14:53:53 -0800226 /*
227 * If the platform is not IPQ8064 and device tree is enabled,
228 * this means ECM started but none of the features are used.
229 * So, just return here.
230 */
231#ifdef CONFIG_OF
232 if (!of_machine_is_compatible("qcom,ipq8064")) {
233 return;
234 }
235#endif
236
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500237 /* call stop on anything that requires a prepare-to-exit signal */
238 printk(KERN_INFO "stop conntrack notifier\n");
239 ecm_conntrack_notifier_stop(1);
240 printk(KERN_INFO "stop front_end_ipv4\n");
241 ecm_front_end_ipv4_stop(1);
Murat Sezgin49465a42014-11-24 15:37:48 -0800242#ifdef ECM_FRONT_END_IPV6_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500243 printk(KERN_INFO "stop front_end_ipv6\n");
244 ecm_front_end_ipv6_stop(1);
Murat Sezgin49465a42014-11-24 15:37:48 -0800245#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500246 printk(KERN_INFO "stop interface\n");
247 ecm_interface_stop(1);
Murat Sezginb3731e82014-11-26 12:20:59 -0800248#ifdef ECM_INTERFACE_BOND_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500249 printk(KERN_INFO "stop bond notifier\n");
250 ecm_bond_notifier_stop(1);
Murat Sezginb3731e82014-11-26 12:20:59 -0800251#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500252 printk(KERN_INFO "defunct all db connections\n");
253 ecm_db_connection_defunct_all();
254
255 /* now call exit on each module */
256 printk(KERN_INFO "exit conntrack notifier\n");
257 ecm_conntrack_notifier_exit();
258 printk(KERN_INFO "exit front_end_ipv4\n");
259 ecm_front_end_ipv4_exit();
Murat Sezgin49465a42014-11-24 15:37:48 -0800260#ifdef ECM_FRONT_END_IPV6_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500261 printk(KERN_INFO "exit front_end_ipv6\n");
262 ecm_front_end_ipv6_exit();
Murat Sezgin49465a42014-11-24 15:37:48 -0800263#endif
Murat Sezginb3731e82014-11-26 12:20:59 -0800264#ifdef ECM_INTERFACE_BOND_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500265 printk(KERN_INFO "exit bond notifier\n");
266 ecm_bond_notifier_exit();
Murat Sezginb3731e82014-11-26 12:20:59 -0800267#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500268 printk(KERN_INFO "exit interface\n");
269 ecm_interface_exit();
Murat Sezginb3731e82014-11-26 12:20:59 -0800270#ifdef ECM_CLASSIFIER_DSCP_ENABLE
Gareth Williams4a02c9b2014-10-10 14:50:33 +0100271 printk(KERN_INFO "exit dscp classifier\n");
272 ecm_classifier_dscp_exit();
Murat Sezginb3731e82014-11-26 12:20:59 -0800273#endif
Hai Shalom81f4e202014-06-04 09:30:27 -0700274#ifdef ECM_CLASSIFIER_HYFI_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500275 printk(KERN_INFO "exit hyfi classifier\n");
276 ecm_classifier_hyfi_rules_exit();
Hai Shalom81f4e202014-06-04 09:30:27 -0700277#endif
Murat Sezginaaaafb42014-11-24 17:02:05 -0800278#ifdef ECM_CLASSIFIER_NL_ENABLE
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500279 printk(KERN_INFO "exit nl classifier\n");
280 ecm_classifier_nl_rules_exit();
Murat Sezginaaaafb42014-11-24 17:02:05 -0800281#endif
Nicolas Costaf46c33b2014-05-15 10:02:00 -0500282 printk(KERN_INFO "exit default classifier\n");
283 ecm_classifier_default_exit();
284 printk(KERN_INFO "exit datagram tracker\n");
285 ecm_tracker_datagram_module_exit();
286 printk(KERN_INFO "exit udp tracker\n");
287 ecm_tracker_udp_module_exit();
288 printk(KERN_INFO "exit tcp tracker\n");
289 ecm_tracker_tcp_module_exit();
290 printk(KERN_INFO "exit db\n");
291 ecm_db_exit();
292 printk(KERN_INFO "exit tracker\n");
293 ecm_tracker_exit();
294
295 printk(KERN_INFO "ECM exit complete\n");
296}
297
298module_init(ecm_init)
299module_exit(ecm_exit)
300
301MODULE_AUTHOR("Qualcomm Atheros, Inc.");
302MODULE_DESCRIPTION("ECM Core");
303#ifdef MODULE_LICENSE
304MODULE_LICENSE("Dual BSD/GPL");
305#endif
306