1/*
2 **************************************************************************
3 * Copyright (c) 2015, 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
17/*
18 * Parental Controls Classifier.
19 * While not implementing parental controls feature itself.
20 * This module provides an interface for customer parental controls systems to interract with the ECM.
21 * This ensures that acceleration will not interfere with parental controls logics, especially DPI.
22 */
23
24#include <linux/version.h>
25#include <linux/types.h>
26#include <linux/ip.h>
27#include <linux/tcp.h>
28#include <linux/module.h>
29#include <linux/skbuff.h>
30#include <linux/icmp.h>
31#include <linux/debugfs.h>
32#include <linux/kthread.h>
33#include <linux/pkt_sched.h>
34#include <linux/string.h>
35#include <linux/ctype.h>
36#include <net/route.h>
37#include <net/ip.h>
38#include <net/tcp.h>
39#include <asm/unaligned.h>
40#include <asm/uaccess.h>	/* for put_user */
41#include <net/ipv6.h>
42#include <linux/inet.h>
43#include <linux/in.h>
44#include <linux/udp.h>
45#include <linux/tcp.h>
46
47#include <linux/netfilter_ipv4.h>
48#include <linux/netfilter_bridge.h>
49#include <net/netfilter/nf_conntrack.h>
50#include <net/netfilter/nf_conntrack_helper.h>
51#include <net/netfilter/nf_conntrack_l4proto.h>
52#include <net/netfilter/nf_conntrack_l3proto.h>
53#include <net/netfilter/nf_conntrack_core.h>
54#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
55#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
56
57/*
58 * Debug output levels
59 * 0 = OFF
60 * 1 = ASSERTS / ERRORS
61 * 2 = 1 + WARN
62 * 3 = 2 + INFO
63 * 4 = 3 + TRACE
64 */
65#define DEBUG_LEVEL ECM_CLASSIFIER_PCC_DEBUG_LEVEL
66
67#include "ecm_types.h"
68#include "ecm_db_types.h"
69#include "ecm_state.h"
70#include "ecm_tracker.h"
71#include "ecm_classifier.h"
72#include "ecm_front_end_types.h"
73#include "ecm_tracker_datagram.h"
74#include "ecm_tracker_udp.h"
75#include "ecm_tracker_tcp.h"
76#include "ecm_db.h"
77#include "ecm_classifier_pcc.h"
78#include "ecm_classifier_pcc_public.h"
79
80/*
81 * Magic numbers
82 */
83#define ECM_CLASSIFIER_PCC_INSTANCE_MAGIC 0x2351
84
85/*
86 * struct ecm_classifier_pcc_instance
87 * 	State per connection for PCC classifier
88 */
89struct ecm_classifier_pcc_instance {
90	struct ecm_classifier_instance base;			/* Base type */
91
92	ecm_classifier_pcc_result_t accel_permit_state;		/* Permission state for acceleration */
93	uint32_t ci_serial;					/* RO: Serial of the connection */
94	long process_jiffies_last;				/* Rate limiting the calls to the registrant */
95	uint32_t reg_calls_to;					/* #calls to registrant */
96	uint32_t reg_calls_from;				/* #calls from registrant */
97
98	struct ecm_classifier_process_response process_response;
99								/* Last process response computed */
100	int refs;						/* Integer to trap we never go negative */
101#if (DEBUG_LEVEL > 0)
102	uint16_t magic;
103#endif
104};
105
106static DEFINE_SPINLOCK(ecm_classifier_pcc_lock);		/* Concurrency control SMP access */
107static int ecm_classifier_pcc_count = 0;			/* Tracks number of instances allocated */
108static struct ecm_classifier_pcc_registrant *ecm_classifier_registrant = NULL;
109								/* Singleton Parent Controls code */
110
111/*
112 * Operational control
113 */
114static bool ecm_classifier_pcc_enabled = false;			/* Enable / disable state of the classifier function */
115
116/*
117 * Debugfs dentry object.
118 */
119static struct dentry *ecm_classifier_pcc_dentry;
120
121/*
122 * ecm_classifier_pcc_register()
123 *	Register a new PCC module.
124 *
125 */
126int ecm_classifier_pcc_register(struct ecm_classifier_pcc_registrant *r)
127{
128	/*
129	 * Hold the module of the registrant
130	 */
131	if (!try_module_get(r->this_module)) {
132		return -ESHUTDOWN;
133	}
134
135	/*
136	 * Hold the registrant we have been given for our purposes.
137	 */
138	r->ref(r);
139
140	spin_lock_bh(&ecm_classifier_pcc_lock);
141	if (ecm_classifier_registrant) {
142		spin_unlock_bh(&ecm_classifier_pcc_lock);
143		DEBUG_WARN("Registrant already\n");
144		module_put(r->this_module);
145		r->deref(r);
146		return -EALREADY;
147	}
148	ecm_classifier_registrant = r;
149	ecm_classifier_pcc_enabled = true;
150	spin_unlock_bh(&ecm_classifier_pcc_lock);
151
152	/*
153	 * Flag a re-generation of all connections is needed
154	 */
155	ecm_db_regeneration_needed();
156	return 0;
157}
158EXPORT_SYMBOL(ecm_classifier_pcc_register);
159
160/*
161 * ecm_classifier_pcc_unregister_begin()
162 *	Begin unregistration process
163 */
164void ecm_classifier_pcc_unregister_begin(struct ecm_classifier_pcc_registrant *r)
165{
166	struct ecm_classifier_pcc_registrant *reg;
167
168	spin_lock_bh(&ecm_classifier_pcc_lock);
169	reg = ecm_classifier_registrant;
170	if (!reg) {
171		spin_unlock_bh(&ecm_classifier_pcc_lock);
172		DEBUG_WARN("No Registrant\n");
173		return;
174	}
175	if (reg != r) {
176		spin_unlock_bh(&ecm_classifier_pcc_lock);
177		DEBUG_WARN("Unexpected registrant, given: %p, expecting: %p\n", r, reg);
178		return;
179	}
180
181	ecm_classifier_registrant = NULL;
182	ecm_classifier_pcc_enabled = false;
183	spin_unlock_bh(&ecm_classifier_pcc_lock);
184
185	/*
186	 * Release our ref upon the registrant that we took when it was registered
187	 */
188	reg->deref(reg);
189	module_put(reg->this_module);
190
191	/*
192	 * Flag a re-generation of all connections is needed
193	 */
194	ecm_db_regeneration_needed();
195}
196EXPORT_SYMBOL(ecm_classifier_pcc_unregister_begin);
197
198/*
199 * ecm_classifier_pcc_permit_accel_v4()
200 *	Permit acceleration.
201 *
202 * Big endian parameters apart from protocol
203 */
204void ecm_classifier_pcc_permit_accel_v4(uint8_t *src_mac, __be32 src_ip, int src_port, uint8_t *dest_mac, __be32 dest_ip, int dest_port, int protocol)
205{
206	ip_addr_t ecm_src_ip;
207	ip_addr_t ecm_dest_ip;
208	struct ecm_db_connection_instance *ci;
209	struct ecm_classifier_instance *classi;
210	struct ecm_classifier_pcc_instance *pcci;
211
212	/*
213	 * Look up ECM connection from the given tuple
214	 */
215	src_port = ntohs(src_port);
216	dest_port = ntohs(dest_port);
217	ECM_NIN4_ADDR_TO_IP_ADDR(ecm_src_ip, src_ip);
218	ECM_NIN4_ADDR_TO_IP_ADDR(ecm_dest_ip, dest_ip);
219
220	{
221		char src_ip_str[40];
222		char dest_ip_str[40];
223
224		ecm_ip_addr_to_string(src_ip_str, ecm_src_ip);
225		ecm_ip_addr_to_string(dest_ip_str, ecm_dest_ip);
226
227		DEBUG_INFO("Permit Accel v4, lookup connection using \n"
228				"Protocol: %d\n"
229				"src: %s:%d\n"
230				"dest: %s:%d\n",
231				protocol,
232				src_ip_str, src_port,
233				dest_ip_str, dest_port);
234	}
235
236	ci = ecm_db_connection_find_and_ref(ecm_src_ip, ecm_dest_ip, protocol, src_port, dest_port);
237	if (!ci) {
238		DEBUG_TRACE("Not found\n");
239		return;
240	}
241
242	/*
243	 * Get the PCC classifier
244	 */
245	classi = ecm_db_connection_assigned_classifier_find_and_ref(ci, ECM_CLASSIFIER_TYPE_PCC);
246	if (!classi) {
247		DEBUG_TRACE("No PCC classi\n");
248		ecm_db_connection_deref(ci);
249		return;
250	}
251	pcci = (struct ecm_classifier_pcc_instance *)classi;
252	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
253
254	/*
255	 * Set the permitted accel state to PERMITTED
256	 * NOTE: When we next see activity on this connection it shall be accelerated (save depending on other classifiers decisions too).
257	 */
258	spin_lock_bh(&ecm_classifier_pcc_lock);
259	pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_PERMITTED;
260	pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
261	pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
262	pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_ACCEL;
263	pcci->reg_calls_from++;
264	spin_unlock_bh(&ecm_classifier_pcc_lock);
265
266	classi->deref(classi);
267	ecm_db_connection_deref(ci);
268}
269EXPORT_SYMBOL(ecm_classifier_pcc_permit_accel_v4);
270
271/*
272 * ecm_classifier_pcc_permit_accel_v6()
273 *	Permit acceleration
274 *
275 * Big endian parameters apart from protocol.
276 *
277 * NOTE: If IPv6 is not supported in ECM this function must still exist as a stub to avoid compilation problems for registrants.
278 */
279void ecm_classifier_pcc_permit_accel_v6(uint8_t *src_mac, struct in6_addr *src_ip, int src_port, uint8_t *dest_mac, struct in6_addr *dest_ip, int dest_port, int protocol)
280{
281#ifdef ECM_IPV6_ENABLE
282	struct in6_addr in6;
283	ip_addr_t ecm_src_ip;
284	ip_addr_t ecm_dest_ip;
285	struct ecm_db_connection_instance *ci;
286	struct ecm_classifier_instance *classi;
287	struct ecm_classifier_pcc_instance *pcci;
288
289	/*
290	 * Look up ECM connection from the given tuple
291	 */
292	src_port = ntohs(src_port);
293	dest_port = ntohs(dest_port);
294	in6 = *src_ip;
295	ECM_NIN6_ADDR_TO_IP_ADDR(ecm_src_ip, in6);
296	in6 = *dest_ip;
297	ECM_NIN6_ADDR_TO_IP_ADDR(ecm_dest_ip, in6);
298
299	{
300		char src_ip_str[40];
301		char dest_ip_str[40];
302
303		ecm_ip_addr_to_string(src_ip_str, ecm_src_ip);
304		ecm_ip_addr_to_string(dest_ip_str, ecm_dest_ip);
305
306		DEBUG_INFO("Permit Accel v6, lookup connection using \n"
307				"Protocol: %d\n"
308				"src: %s:%d\n"
309				"dest: %s:%d\n",
310				protocol,
311				src_ip_str, src_port,
312				dest_ip_str, dest_port);
313	}
314
315	ci = ecm_db_connection_find_and_ref(ecm_src_ip, ecm_dest_ip, protocol, src_port, dest_port);
316	if (!ci) {
317		DEBUG_TRACE("Not found\n");
318		return;
319	}
320
321	/*
322	 * Get the PCC classifier
323	 */
324	classi = ecm_db_connection_assigned_classifier_find_and_ref(ci, ECM_CLASSIFIER_TYPE_PCC);
325	if (!classi) {
326		DEBUG_TRACE("No PCC classi\n");
327		ecm_db_connection_deref(ci);
328		return;
329	}
330	pcci = (struct ecm_classifier_pcc_instance *)classi;
331	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
332
333	/*
334	 * Set the permitted accel state to PERMITTED
335	 * NOTE: When we next see activity on this connection it shall be accelerated (save depending on other classifiers decisions too).
336	 */
337	spin_lock_bh(&ecm_classifier_pcc_lock);
338	pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_PERMITTED;
339	pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
340	pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
341	pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_ACCEL;
342	pcci->reg_calls_from++;
343	spin_unlock_bh(&ecm_classifier_pcc_lock);
344
345	classi->deref(classi);
346	ecm_db_connection_deref(ci);
347#endif
348}
349EXPORT_SYMBOL(ecm_classifier_pcc_permit_accel_v6);
350
351/*
352 * ecm_classifier_pcc_deny_accel_v4()
353 *	Deny acceleration
354 */
355void ecm_classifier_pcc_deny_accel_v4(uint8_t *src_mac, __be32 src_ip, int src_port, uint8_t *dest_mac, __be32 dest_ip, int dest_port, int protocol)
356{
357	ip_addr_t ecm_src_ip;
358	ip_addr_t ecm_dest_ip;
359	struct ecm_db_connection_instance *ci;
360	struct ecm_classifier_instance *classi;
361	struct ecm_classifier_pcc_instance *pcci;
362	struct ecm_front_end_connection_instance *feci;
363
364	/*
365	 * Look up ECM connection from the given tuple
366	 */
367	src_port = ntohs(src_port);
368	dest_port = ntohs(dest_port);
369	ECM_NIN4_ADDR_TO_IP_ADDR(ecm_src_ip, src_ip);
370	ECM_NIN4_ADDR_TO_IP_ADDR(ecm_dest_ip, dest_ip);
371
372	{
373		char src_ip_str[40];
374		char dest_ip_str[40];
375
376		ecm_ip_addr_to_string(src_ip_str, ecm_src_ip);
377		ecm_ip_addr_to_string(dest_ip_str, ecm_dest_ip);
378
379		DEBUG_INFO("Deny Accel v4, lookup connection using \n"
380				"Protocol: %d\n"
381				"src: %s:%d\n"
382				"dest: %s:%d\n",
383				protocol,
384				src_ip_str, src_port,
385				dest_ip_str, dest_port);
386	}
387
388	ci = ecm_db_connection_find_and_ref(ecm_src_ip, ecm_dest_ip, protocol, src_port, dest_port);
389	if (!ci) {
390		DEBUG_TRACE("Not found\n");
391		return;
392	}
393
394	/*
395	 * Get the PCC classifier
396	 */
397	classi = ecm_db_connection_assigned_classifier_find_and_ref(ci, ECM_CLASSIFIER_TYPE_PCC);
398	if (!classi) {
399		DEBUG_TRACE("No PCC classi\n");
400		ecm_db_connection_deref(ci);
401		return;
402	}
403	pcci = (struct ecm_classifier_pcc_instance *)classi;
404	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
405
406	/*
407	 * Set the permitted accel state to DENIED
408	 * NOTE: When we next see activity on this connection it shall be accelerated (save depending on other classifiers decisions too).
409	 */
410	spin_lock_bh(&ecm_classifier_pcc_lock);
411	pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_DENIED;
412	pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
413	pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
414	pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
415	pcci->reg_calls_from++;
416	spin_unlock_bh(&ecm_classifier_pcc_lock);
417
418	/*
419	 * Get the front end and issue a deceleration
420	 * If the connection is not accelerated anyway this will have no effect
421	 */
422	feci = ecm_db_connection_front_end_get_and_ref(ci);
423	feci->decelerate(feci);
424	feci->deref(feci);
425
426	classi->deref(classi);
427	ecm_db_connection_deref(ci);
428}
429EXPORT_SYMBOL(ecm_classifier_pcc_deny_accel_v4);
430
431/*
432 * ecm_classifier_pcc_deny_accel_v6()
433 *	Deny acceleration
434 *
435 * NOTE: If IPv6 is not supported in ECM this function must still exist as a stub to avoid compilation problems for registrants.
436 */
437void ecm_classifier_pcc_deny_accel_v6(uint8_t *src_mac, struct in6_addr *src_ip, int src_port, uint8_t *dest_mac, struct in6_addr *dest_ip, int dest_port, int protocol)
438{
439#ifdef ECM_IPV6_ENABLE
440	struct in6_addr in6;
441	ip_addr_t ecm_src_ip;
442	ip_addr_t ecm_dest_ip;
443	struct ecm_db_connection_instance *ci;
444	struct ecm_classifier_instance *classi;
445	struct ecm_classifier_pcc_instance *pcci;
446	struct ecm_front_end_connection_instance *feci;
447
448	/*
449	 * Look up ECM connection from the given tuple
450	 */
451	src_port = ntohs(src_port);
452	dest_port = ntohs(dest_port);
453	in6 = *src_ip;
454	ECM_NIN6_ADDR_TO_IP_ADDR(ecm_src_ip, in6);
455	in6 = *dest_ip;
456	ECM_NIN6_ADDR_TO_IP_ADDR(ecm_dest_ip, in6);
457
458	{
459		char src_ip_str[40];
460		char dest_ip_str[40];
461
462		ecm_ip_addr_to_string(src_ip_str, ecm_src_ip);
463		ecm_ip_addr_to_string(dest_ip_str, ecm_dest_ip);
464
465		DEBUG_INFO("Deny Accel v6, lookup connection using \n"
466				"Protocol: %d\n"
467				"src: %s:%d\n"
468				"dest: %s:%d\n",
469				protocol,
470				src_ip_str, src_port,
471				dest_ip_str, dest_port);
472	}
473
474	ci = ecm_db_connection_find_and_ref(ecm_src_ip, ecm_dest_ip, protocol, src_port, dest_port);
475	if (!ci) {
476		DEBUG_TRACE("Not found\n");
477		return;
478	}
479
480	/*
481	 * Get the PCC classifier
482	 */
483	classi = ecm_db_connection_assigned_classifier_find_and_ref(ci, ECM_CLASSIFIER_TYPE_PCC);
484	if (!classi) {
485		DEBUG_TRACE("No PCC classi\n");
486		ecm_db_connection_deref(ci);
487		return;
488	}
489	pcci = (struct ecm_classifier_pcc_instance *)classi;
490	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
491
492	/*
493	 * Set the permitted accel state to DENIED
494	 * NOTE: When we next see activity on this connection it shall be accelerated (save depending on other classifiers decisions too).
495	 */
496	spin_lock_bh(&ecm_classifier_pcc_lock);
497	pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_DENIED;
498	pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
499	pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
500	pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
501	pcci->reg_calls_from++;
502	spin_unlock_bh(&ecm_classifier_pcc_lock);
503
504	/*
505	 * Get the front end and issue a deceleration
506	 * If the connection is not accelerated anyway this will have no effect
507	 */
508	feci = ecm_db_connection_front_end_get_and_ref(ci);
509	feci->decelerate(feci);
510	feci->deref(feci);
511
512	classi->deref(classi);
513	ecm_db_connection_deref(ci);
514#endif
515}
516EXPORT_SYMBOL(ecm_classifier_pcc_deny_accel_v6);
517
518/*
519 * ecm_classifier_pcc_unregister_force()
520 *	Unregister the registrant, if any
521 */
522static void ecm_classifier_pcc_unregister_force(struct ecm_classifier_pcc_instance *pcci)
523{
524	struct ecm_classifier_pcc_registrant *reg;
525
526	spin_lock_bh(&ecm_classifier_pcc_lock);
527	reg = ecm_classifier_registrant;
528	if (!reg) {
529		spin_unlock_bh(&ecm_classifier_pcc_lock);
530		return;
531	}
532	ecm_classifier_registrant = NULL;
533	ecm_classifier_pcc_enabled = false;
534	spin_unlock_bh(&ecm_classifier_pcc_lock);
535
536	/*
537	 * Release our ref upon the registrant that we took when it was registered
538	 */
539	DEBUG_INFO("Force unregistration of: %p\n", reg);
540	reg->deref(reg);
541
542	/*
543	 * Release hold on registrant module
544	 */
545	module_put(reg->this_module);
546
547	/*
548	 * Flag a re-generation of all connections is needed
549	 */
550	ecm_db_regeneration_needed();
551}
552
553/*
554 * _ecm_classifier_pcc_ref()
555 *	Ref
556 */
557static void _ecm_classifier_pcc_ref(struct ecm_classifier_pcc_instance *pcci)
558{
559	pcci->refs++;
560	DEBUG_TRACE("%p: pcci ref %d\n", pcci, pcci->refs);
561	DEBUG_ASSERT(pcci->refs > 0, "%p: ref wrap\n", pcci);
562}
563
564/*
565 * ecm_classifier_pcc_ref()
566 *	Ref
567 */
568static void ecm_classifier_pcc_ref(struct ecm_classifier_instance *ci)
569{
570	struct ecm_classifier_pcc_instance *pcci;
571	pcci = (struct ecm_classifier_pcc_instance *)ci;
572
573	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
574	spin_lock_bh(&ecm_classifier_pcc_lock);
575	_ecm_classifier_pcc_ref(pcci);
576	spin_unlock_bh(&ecm_classifier_pcc_lock);
577}
578
579/*
580 * ecm_classifier_pcc_deref()
581 *	Deref
582 */
583static int ecm_classifier_pcc_deref(struct ecm_classifier_instance *ci)
584{
585	struct ecm_classifier_pcc_instance *pcci;
586	pcci = (struct ecm_classifier_pcc_instance *)ci;
587
588	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
589	spin_lock_bh(&ecm_classifier_pcc_lock);
590	pcci->refs--;
591	DEBUG_ASSERT(pcci->refs >= 0, "%p: refs wrapped\n", pcci);
592	DEBUG_TRACE("%p: Parental Controls classifier deref %d\n", pcci, pcci->refs);
593	if (pcci->refs) {
594		int refs = pcci->refs;
595		spin_unlock_bh(&ecm_classifier_pcc_lock);
596		return refs;
597	}
598
599	/*
600	 * Object to be destroyed
601	 */
602	ecm_classifier_pcc_count--;
603	DEBUG_ASSERT(ecm_classifier_pcc_count >= 0, "%p: ecm_classifier_pcc_count wrap\n", pcci);
604
605	spin_unlock_bh(&ecm_classifier_pcc_lock);
606
607	/*
608	 * Final
609	 */
610	DEBUG_INFO("%p: Final Parental Controls classifier instance\n", pcci);
611	kfree(pcci);
612
613	return 0;
614}
615
616/*
617 * ecm_classifier_pcc_process()
618 *	Process new packet
619 *
620 * NOTE: This function would only ever be called if all other classifiers have failed.
621 */
622static void ecm_classifier_pcc_process(struct ecm_classifier_instance *aci, ecm_tracker_sender_type_t sender,
623									struct ecm_tracker_ip_header *ip_hdr, struct sk_buff *skb,
624									struct ecm_classifier_process_response *process_response)
625{
626	struct ecm_classifier_pcc_instance *pcci = (struct ecm_classifier_pcc_instance *)aci;
627	ecm_classifier_pcc_result_t accel_permit_state;
628	ecm_classifier_pcc_result_t reg_result;
629	struct ecm_db_connection_instance *ci;
630	long jiffies_now;
631	int ip_version;
632	uint8_t src_mac[ETH_ALEN];
633	uint8_t dest_mac[ETH_ALEN];
634	int protocol;
635	int src_port;
636	int dst_port;
637	ip_addr_t src_ip;
638	ip_addr_t dst_ip;
639	struct ecm_classifier_pcc_registrant *registrant;
640
641	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: invalid state magic\n", pcci);
642
643	/*
644	 * Get connection
645	 */
646	ci = ecm_db_connection_serial_find_and_ref(pcci->ci_serial);
647	if (!ci) {
648		/*
649		 * Connection has gone from under us
650		 */
651		spin_lock_bh(&ecm_classifier_pcc_lock);
652		goto not_relevant;
653	}
654
655	/*
656	 * Early detection of DNS server port
657	 */
658	dst_port = ecm_db_connection_to_port_get(ci);
659
660	spin_lock_bh(&ecm_classifier_pcc_lock);
661
662	/*
663	 * Not relevant to the connection if not enabled.
664	 */
665	if (unlikely(!ecm_classifier_pcc_enabled)) {
666		/*
667		 * Not relevant.
668		 */
669		goto not_relevant;
670	}
671
672	/*
673	 * What is our acceleration permit state?
674	 * If it is something other than ECM_CLASSIFIER_PCC_RESULT_NOT_YET then we have a definitive result already.
675	 */
676	accel_permit_state = pcci->accel_permit_state;
677	if (accel_permit_state != ECM_CLASSIFIER_PCC_RESULT_NOT_YET) {
678		*process_response = pcci->process_response;
679		spin_unlock_bh(&ecm_classifier_pcc_lock);
680		ecm_db_connection_deref(ci);
681		return;
682	}
683
684	/*
685	 * If the destination port is to DNS server then we implicitly deny acceleration
686	 */
687	if (dst_port == 53) {
688		/*
689		 * By setting the permit state to DENIED we will always deny from this point on
690		 */
691		pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_DENIED;
692		goto deny_accel;
693	}
694
695	/*
696	 * We need to call to the registrant BUT we cannot do this at a rate that exceeds 1/sec
697	 * NOTE: Not worried about wrap around, it's only one second.
698	 */
699	jiffies_now = jiffies;
700	if ((jiffies_now - pcci->process_jiffies_last) < HZ) {
701		/*
702		 * We cannot permit acceleration just yet
703		 * Deny accel but don't change the permit state - we try again later
704		 */
705		goto deny_accel;
706	}
707	pcci->process_jiffies_last = jiffies_now;
708
709	/*
710	 * We have to call out to our registrant to see if we can get permission to accelerate.
711	 * Get our registrant
712	 */
713	registrant = ecm_classifier_registrant;
714	registrant->ref(registrant);
715
716	/*
717	 * Bump reg calls made to the registrant.
718	 */
719	pcci->reg_calls_to++;
720
721	spin_unlock_bh(&ecm_classifier_pcc_lock);
722
723	/*
724	 * See if we can hold the registrant module - it may be unloading.
725	 */
726	if (!try_module_get(registrant->this_module)) {
727		/*
728		 * Module is unloading.
729		 */
730		registrant->deref(registrant);
731
732		/*
733		 * Force unregistration
734		 */
735		ecm_classifier_pcc_unregister_force(pcci);
736
737		/*
738		 * We are implicitly "not relevant".
739		 */
740		spin_lock_bh(&ecm_classifier_pcc_lock);
741		goto not_relevant;
742	}
743
744	/*
745	 * Ask the registrant if we may accelerate (big endian)
746	 */
747	ip_version = ecm_db_connection_ip_version_get(ci);
748	protocol = ecm_db_connection_protocol_get(ci);
749	ecm_db_connection_from_address_get(ci, src_ip);
750	src_port = htons(ecm_db_connection_from_port_get(ci));
751	dst_port = htons(dst_port);
752	ecm_db_connection_to_address_get(ci, dst_ip);
753	ecm_db_connection_from_node_address_get(ci, src_mac);
754	ecm_db_connection_to_node_address_get(ci, dest_mac);
755
756	/*
757	 * Default is permitted in case ip_version is unsupported here
758	 */
759	reg_result = ECM_CLASSIFIER_PCC_RESULT_PERMITTED;
760	if (ip_version == 4) {
761		__be32 src_ip4;
762		__be32 dest_ip4;
763
764		ECM_IP_ADDR_TO_NIN4_ADDR(src_ip4, src_ip);
765		ECM_IP_ADDR_TO_NIN4_ADDR(dest_ip4, dst_ip);
766		reg_result = registrant->okay_to_accel_v4(registrant, src_mac, src_ip4, src_port, dest_mac, dest_ip4, dst_port, protocol);
767	}
768#ifdef ECM_IPV6_ENABLE
769	if (ip_version == 6) {
770		struct in6_addr src_ip6;
771		struct in6_addr dest_ip6;
772		ECM_IP_ADDR_TO_NIN6_ADDR(src_ip6, src_ip);
773		ECM_IP_ADDR_TO_NIN6_ADDR(dest_ip6, dst_ip);
774		reg_result = registrant->okay_to_accel_v6(registrant, src_mac, &src_ip6, src_port, dest_mac, &dest_ip6, dst_port, protocol);
775	}
776#endif
777
778	/*
779	 * Release the ref taken for this call
780	 */
781	registrant->deref(registrant);
782
783	/*
784	 * Release the module ref taken.
785	 */
786	module_put(registrant->this_module);
787
788	/*
789	 * Handle the result
790	 */
791	switch (reg_result) {
792	case ECM_CLASSIFIER_PCC_RESULT_NOT_YET:
793		/*
794		 * Deny accel but don't change the permit state - we try again later
795		 */
796		spin_lock_bh(&ecm_classifier_pcc_lock);
797		goto deny_accel;
798	case ECM_CLASSIFIER_PCC_RESULT_DENIED:
799		/*
800		 * Deny accel and set the permit state to denied - this connection is denied from this point on.
801		 */
802		spin_lock_bh(&ecm_classifier_pcc_lock);
803		pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_DENIED;
804		goto deny_accel;
805	case ECM_CLASSIFIER_PCC_RESULT_PERMITTED:
806		break;
807	default:
808		DEBUG_ASSERT(false, "Unhandled result: %d\n", reg_result);
809	}
810
811	/*
812	 * Acceleration is permitted
813	 */
814	spin_lock_bh(&ecm_classifier_pcc_lock);
815	pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_PERMITTED;
816	pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
817	pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
818	pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_ACCEL;
819	*process_response = pcci->process_response;
820	spin_unlock_bh(&ecm_classifier_pcc_lock);
821	ecm_db_connection_deref(ci);
822
823	return;
824
825not_relevant:
826
827	/*
828	 * ecm_classifier_pcc_lock MUST be held
829	 */
830	pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_NO;
831	pcci->process_response.process_actions = 0;
832	*process_response = pcci->process_response;
833	spin_unlock_bh(&ecm_classifier_pcc_lock);
834	ecm_db_connection_deref(ci);
835	return;
836
837deny_accel:
838
839	/*
840	 * ecm_classifier_pcc_lock MUST be held
841	 */
842	pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
843	pcci->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
844	pcci->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
845	*process_response = pcci->process_response;
846	spin_unlock_bh(&ecm_classifier_pcc_lock);
847	ecm_db_connection_deref(ci);
848	return;
849
850}
851
852/*
853 * ecm_classifier_pcc_type_get()
854 *	Get type of classifier this is
855 */
856static ecm_classifier_type_t ecm_classifier_pcc_type_get(struct ecm_classifier_instance *aci)
857{
858	struct ecm_classifier_pcc_instance *pcci;
859	pcci = (struct ecm_classifier_pcc_instance *)aci;
860
861	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
862	return ECM_CLASSIFIER_TYPE_PCC;
863}
864
865/*
866 * ecm_classifier_pcc_reclassify_allowed()
867 *	Get whether reclassification is allowed
868 */
869static bool ecm_classifier_pcc_reclassify_allowed(struct ecm_classifier_instance *aci)
870{
871	struct ecm_classifier_pcc_instance *pcci;
872	pcci = (struct ecm_classifier_pcc_instance *)aci;
873
874	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
875	return true;
876}
877
878/*
879 * ecm_classifier_pcc_reclassify()
880 *	Reclassify
881 */
882static void ecm_classifier_pcc_reclassify(struct ecm_classifier_instance *aci)
883{
884	struct ecm_classifier_pcc_instance *pcci;
885	pcci = (struct ecm_classifier_pcc_instance *)aci;
886	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
887
888	/*
889	 * Connection needs to be reset to 'as new'
890	 * NOTE: Implicitly the connection would have been decelerated now so we don't need to worry about that.
891	 */
892	spin_lock_bh(&ecm_classifier_pcc_lock);
893	pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_NOT_YET;
894
895	/*
896	 * Reset jiffies for rate limiting registrant calls
897	 */
898	pcci->process_jiffies_last = jiffies;
899
900	spin_unlock_bh(&ecm_classifier_pcc_lock);
901}
902
903/*
904 * ecm_classifier_pcc_last_process_response_get()
905 *	Get result code returned by the last process call
906 */
907static void ecm_classifier_pcc_last_process_response_get(struct ecm_classifier_instance *aci,
908							struct ecm_classifier_process_response *process_response)
909{
910	struct ecm_classifier_pcc_instance *pcci;
911	pcci = (struct ecm_classifier_pcc_instance *)aci;
912	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
913
914	spin_lock_bh(&ecm_classifier_pcc_lock);
915	*process_response = pcci->process_response;
916	spin_unlock_bh(&ecm_classifier_pcc_lock);
917}
918
919/*
920 * ecm_classifier_pcc_sync_to_v4()
921 *	Front end is pushing accel engine state to us
922 */
923static void ecm_classifier_pcc_sync_to_v4(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_sync *sync)
924{
925	struct ecm_classifier_pcc_instance *pcci __attribute__((unused));
926
927	pcci = (struct ecm_classifier_pcc_instance *)aci;
928	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
929}
930
931/*
932 * ecm_classifier_pcc_sync_from_v4()
933 *	Front end is retrieving accel engine state from us
934 */
935static void ecm_classifier_pcc_sync_from_v4(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_create *ecrc)
936{
937	struct ecm_classifier_pcc_instance *pcci __attribute__((unused));
938
939	pcci = (struct ecm_classifier_pcc_instance *)aci;
940	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
941}
942
943/*
944 * ecm_classifier_pcc_sync_to_v6()
945 *	Front end is pushing accel engine state to us
946 */
947static void ecm_classifier_pcc_sync_to_v6(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_sync *sync)
948{
949	struct ecm_classifier_pcc_instance *pcci __attribute__((unused));
950
951	pcci = (struct ecm_classifier_pcc_instance *)aci;
952	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
953}
954
955/*
956 * ecm_classifier_pcc_sync_from_v6()
957 *	Front end is retrieving accel engine state from us
958 */
959static void ecm_classifier_pcc_sync_from_v6(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_create *ecrc)
960{
961	struct ecm_classifier_pcc_instance *pcci __attribute__((unused));
962
963	pcci = (struct ecm_classifier_pcc_instance *)aci;
964	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
965}
966
967#ifdef ECM_STATE_OUTPUT_ENABLE
968/*
969 * ecm_classifier_pcc_state_get()
970 *	Return state
971 */
972static int ecm_classifier_pcc_state_get(struct ecm_classifier_instance *ci, struct ecm_state_file_instance *sfi)
973{
974	int result;
975	struct ecm_classifier_pcc_instance *pcci;
976	struct ecm_classifier_process_response process_response;
977	ecm_classifier_pcc_result_t accel_permit_state;
978	uint32_t reg_calls_to;
979	uint32_t reg_calls_from;
980
981	pcci = (struct ecm_classifier_pcc_instance *)ci;
982	DEBUG_CHECK_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC, "%p: magic failed", pcci);
983
984	if ((result = ecm_state_prefix_add(sfi, "pcc"))) {
985		return result;
986	}
987
988	spin_lock_bh(&ecm_classifier_pcc_lock);
989	accel_permit_state = pcci->accel_permit_state;
990	process_response = pcci->process_response;
991	reg_calls_to = pcci->reg_calls_to;
992	reg_calls_from = pcci->reg_calls_from;
993	spin_unlock_bh(&ecm_classifier_pcc_lock);
994
995
996	if ((result = ecm_state_write(sfi, "accel_permit_state", "%d", accel_permit_state))) {
997		return result;
998	}
999	if ((result = ecm_state_write(sfi, "reg_calls_to", "%d", reg_calls_to))) {
1000		return result;
1001	}
1002	if ((result = ecm_state_write(sfi, "reg_calls_from", "%d", reg_calls_from))) {
1003		return result;
1004	}
1005
1006	/*
1007	 * Output our last process response
1008	 */
1009	if ((result = ecm_classifier_process_response_state_get(sfi, &process_response))) {
1010		return result;
1011	}
1012
1013	if ((result = ecm_state_prefix_remove(sfi))) {
1014		return result;
1015	}
1016
1017	return ecm_state_prefix_remove(sfi);
1018}
1019#endif
1020
1021/*
1022 * ecm_classifier_pcc_instance_alloc()
1023 *	Allocate an instance of the Parental Controls classifier
1024 */
1025struct ecm_classifier_pcc_instance *ecm_classifier_pcc_instance_alloc(struct ecm_db_connection_instance *ci)
1026{
1027	struct ecm_classifier_pcc_instance *pcci;
1028	struct ecm_classifier_instance *cdi;
1029
1030	/*
1031	 * Allocate the instance
1032	 */
1033	pcci = (struct ecm_classifier_pcc_instance *)kzalloc(sizeof(struct ecm_classifier_pcc_instance), GFP_ATOMIC | __GFP_NOWARN);
1034	if (!pcci) {
1035		DEBUG_WARN("Failed to allocate Parental Controls Classifier instance\n");
1036		return NULL;
1037	}
1038
1039	DEBUG_SET_MAGIC(pcci, ECM_CLASSIFIER_PCC_INSTANCE_MAGIC);
1040	pcci->refs = 1;
1041	pcci->ci_serial = ecm_db_connection_serial_get(ci);
1042
1043	/*
1044	 * We are relevant to the connection at this time
1045	 */
1046	pcci->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
1047
1048	/*
1049	 * Don't know yet whether we are allowed to accelerate - need to query the registrant
1050	 */
1051	pcci->accel_permit_state = ECM_CLASSIFIER_PCC_RESULT_NOT_YET;
1052
1053	/*
1054	 * Reset jiffies for rate limiting registrant calls
1055	 */
1056	pcci->process_jiffies_last = jiffies;
1057
1058	/*
1059	 * Methods generic to all classifiers.
1060	 */
1061	cdi = (struct ecm_classifier_instance *)pcci;
1062	cdi->process = ecm_classifier_pcc_process;
1063	cdi->sync_from_v4 = ecm_classifier_pcc_sync_from_v4;
1064	cdi->sync_to_v4 = ecm_classifier_pcc_sync_to_v4;
1065	cdi->sync_from_v6 = ecm_classifier_pcc_sync_from_v6;
1066	cdi->sync_to_v6 = ecm_classifier_pcc_sync_to_v6;
1067	cdi->type_get = ecm_classifier_pcc_type_get;
1068	cdi->reclassify_allowed = ecm_classifier_pcc_reclassify_allowed;
1069	cdi->reclassify = ecm_classifier_pcc_reclassify;
1070	cdi->last_process_response_get = ecm_classifier_pcc_last_process_response_get;
1071#ifdef ECM_STATE_OUTPUT_ENABLE
1072	cdi->state_get = ecm_classifier_pcc_state_get;
1073#endif
1074	cdi->ref = ecm_classifier_pcc_ref;
1075	cdi->deref = ecm_classifier_pcc_deref;
1076
1077	/*
1078	 * Increment stats
1079	 */
1080	spin_lock_bh(&ecm_classifier_pcc_lock);
1081	ecm_classifier_pcc_count++;
1082	DEBUG_ASSERT(ecm_classifier_pcc_count > 0, "%p: ecm_classifier_pcc_count wrap\n", pcci);
1083	spin_unlock_bh(&ecm_classifier_pcc_lock);
1084
1085	DEBUG_INFO("Parental Controls classifier instance alloc: %p\n", pcci);
1086	return pcci;
1087}
1088EXPORT_SYMBOL(ecm_classifier_pcc_instance_alloc);
1089
1090/*
1091 * ecm_classifier_pcc_init()
1092 */
1093int ecm_classifier_pcc_init(struct dentry *dentry)
1094{
1095	DEBUG_INFO("Parental Controls classifier Module init\n");
1096
1097	ecm_classifier_pcc_dentry = debugfs_create_dir("ecm_classifier_pcc", dentry);
1098	if (!ecm_classifier_pcc_dentry) {
1099		DEBUG_ERROR("Failed to create ecm pcc directory in debugfs\n");
1100		return -1;
1101	}
1102
1103	if (!debugfs_create_u32("enabled", S_IRUGO, ecm_classifier_pcc_dentry,
1104					(u32 *)&ecm_classifier_pcc_enabled)) {
1105		DEBUG_ERROR("Failed to create pcc enabled file in debugfs\n");
1106		debugfs_remove_recursive(ecm_classifier_pcc_dentry);
1107		return -1;
1108	}
1109
1110	return 0;
1111}
1112EXPORT_SYMBOL(ecm_classifier_pcc_init);
1113
1114/*
1115 * ecm_classifier_pcc_exit()
1116 */
1117void ecm_classifier_pcc_exit(void)
1118{
1119	DEBUG_INFO("Parental Controls classifier Module exit\n");
1120
1121	/*
1122	 * Remove the debugfs files recursively.
1123	 */
1124	if (ecm_classifier_pcc_dentry) {
1125		debugfs_remove_recursive(ecm_classifier_pcc_dentry);
1126	}
1127
1128}
1129EXPORT_SYMBOL(ecm_classifier_pcc_exit);
1130