blob: 0dac519e809d10066840a91488ea438c5ddb30d7 [file] [log] [blame]
Murat Sezginc725ad82016-04-13 17:12:50 -07001/*
2 **************************************************************************
Murat Sezginf4f7ab42018-10-12 17:01:46 -07003 * Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
Murat Sezginc725ad82016-04-13 17:12:50 -07004 * 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#include <linux/version.h>
18#include <linux/types.h>
19#include <net/ip.h>
20#include <net/ipv6.h>
21#include <linux/inet.h>
22#include <linux/etherdevice.h>
23
24/*
25 * Debug output levels
26 * 0 = OFF
27 * 1 = ASSERTS / ERRORS
28 * 2 = 1 + WARN
29 * 3 = 2 + INFO
30 * 4 = 3 + TRACE
31 */
32#define DEBUG_LEVEL ECM_CLASSIFIER_DEBUG_LEVEL
33
34#include "ecm_types.h"
35#include "ecm_db_types.h"
36#include "ecm_state.h"
37#include "ecm_tracker.h"
38#include "ecm_classifier.h"
Murat Sezginc890e0c2016-09-01 11:17:17 -070039#include "ecm_front_end_types.h"
Murat Sezginc725ad82016-04-13 17:12:50 -070040#include "ecm_db.h"
41#ifdef ECM_CLASSIFIER_NL_ENABLE
42#include "ecm_classifier_nl.h"
43#endif
44#ifdef ECM_CLASSIFIER_HYFI_ENABLE
45#include "ecm_classifier_hyfi.h"
46#endif
47#ifdef ECM_CLASSIFIER_DSCP_ENABLE
48#include "ecm_classifier_dscp.h"
49#endif
50#ifdef ECM_CLASSIFIER_PCC_ENABLE
51#include "ecm_classifier_pcc.h"
52#endif
Murat Sezginf4f7ab42018-10-12 17:01:46 -070053#ifdef ECM_CLASSIFIER_MARK_ENABLE
54#include "ecm_classifier_mark.h"
55#endif
Murat Sezginc725ad82016-04-13 17:12:50 -070056
57/*
58 * ecm_classifier_assign_classifier()
59 * Instantiate and assign classifier of type upon the connection, also returning it if it could be allocated.
60 */
61struct ecm_classifier_instance *ecm_classifier_assign_classifier(struct ecm_db_connection_instance *ci, ecm_classifier_type_t type)
62{
63 DEBUG_TRACE("%p: Assign classifier of type: %d\n", ci, type);
64 DEBUG_ASSERT(type != ECM_CLASSIFIER_TYPE_DEFAULT, "Must never need to instantiate default type in this way");
65
66#ifdef ECM_CLASSIFIER_PCC_ENABLE
67 if (type == ECM_CLASSIFIER_TYPE_PCC) {
68 struct ecm_classifier_pcc_instance *pcci;
69 pcci = ecm_classifier_pcc_instance_alloc(ci);
70 if (!pcci) {
71 DEBUG_TRACE("%p: Failed to create Parental Controls classifier\n", ci);
72 return NULL;
73 }
74 DEBUG_TRACE("%p: Created Parental Controls classifier: %p\n", ci, pcci);
75 ecm_db_connection_classifier_assign(ci, (struct ecm_classifier_instance *)pcci);
76 return (struct ecm_classifier_instance *)pcci;
77 }
78#endif
79
80#ifdef ECM_CLASSIFIER_NL_ENABLE
81 if (type == ECM_CLASSIFIER_TYPE_NL) {
82 struct ecm_classifier_nl_instance *cnli;
83 cnli = ecm_classifier_nl_instance_alloc(ci);
84 if (!cnli) {
85 DEBUG_TRACE("%p: Failed to create Netlink classifier\n", ci);
86 return NULL;
87 }
88 DEBUG_TRACE("%p: Created Netlink classifier: %p\n", ci, cnli);
89 ecm_db_connection_classifier_assign(ci, (struct ecm_classifier_instance *)cnli);
90 return (struct ecm_classifier_instance *)cnli;
91 }
92#endif
93
94#ifdef ECM_CLASSIFIER_DSCP_ENABLE
95 if (type == ECM_CLASSIFIER_TYPE_DSCP) {
96 struct ecm_classifier_dscp_instance *cdscpi;
97 cdscpi = ecm_classifier_dscp_instance_alloc(ci);
98 if (!cdscpi) {
99 DEBUG_TRACE("%p: Failed to create DSCP classifier\n", ci);
100 return NULL;
101 }
102 DEBUG_TRACE("%p: Created DSCP classifier: %p\n", ci, cdscpi);
103 ecm_db_connection_classifier_assign(ci, (struct ecm_classifier_instance *)cdscpi);
104 return (struct ecm_classifier_instance *)cdscpi;
105 }
106#endif
107
108#ifdef ECM_CLASSIFIER_HYFI_ENABLE
109 if (type == ECM_CLASSIFIER_TYPE_HYFI) {
110 struct ecm_classifier_hyfi_instance *chfi;
111 chfi = ecm_classifier_hyfi_instance_alloc(ci);
112 if (!chfi) {
113 DEBUG_TRACE("%p: Failed to create HyFi classifier\n", ci);
114 return NULL;
115 }
116 DEBUG_TRACE("%p: Created HyFi classifier: %p\n", ci, chfi);
117 ecm_db_connection_classifier_assign(ci, (struct ecm_classifier_instance *)chfi);
118 return (struct ecm_classifier_instance *)chfi;
119 }
120#endif
Murat Sezginf4f7ab42018-10-12 17:01:46 -0700121#ifdef ECM_CLASSIFIER_MARK_ENABLE
122 if (type == ECM_CLASSIFIER_TYPE_MARK) {
123 struct ecm_classifier_mark_instance *ecmi;
124 ecmi = ecm_classifier_mark_instance_alloc(ci);
125 if (!ecmi) {
126 DEBUG_TRACE("%p: Failed to create mark classifier\n", ci);
127 return NULL;
128 }
129 DEBUG_TRACE("%p: Created mark classifier: %p\n", ci, ecmi);
130 ecm_db_connection_classifier_assign(ci, (struct ecm_classifier_instance *)ecmi);
131 return (struct ecm_classifier_instance *)ecmi;
132 }
133#endif
Murat Sezginc725ad82016-04-13 17:12:50 -0700134
135 DEBUG_ASSERT(NULL, "%p: Unsupported type: %d\n", ci, type);
136 return NULL;
137}
138
139/*
140 * ecm_classifier_reclassify()
141 * Signal reclassify upon the assigned classifiers.
142 *
143 * Classifiers that unassigned themselves we TRY to re-instantiate them.
144 * Returns false if the function is not able to instantiate all missing classifiers.
145 * This function does not release and references to classifiers in the assignments[].
146 */
147bool ecm_classifier_reclassify(struct ecm_db_connection_instance *ci, int assignment_count, struct ecm_classifier_instance *assignments[])
148{
149 ecm_classifier_type_t classifier_type;
150 int i;
151 bool full_reclassification = true;
152
153 /*
154 * assignment_count will always be <= the number of classifier types available
155 */
156 for (i = 0, classifier_type = ECM_CLASSIFIER_TYPE_DEFAULT; i < assignment_count; ++i, ++classifier_type) {
157 ecm_classifier_type_t aci_type;
158 struct ecm_classifier_instance *aci;
159
160 aci = assignments[i];
161 aci_type = aci->type_get(aci);
162 DEBUG_TRACE("%p: Reclassify: %d\n", ci, aci_type);
163 aci->reclassify(aci);
164
165 /*
166 * If the connection has a full complement of assigned classifiers then these will match 1:1 with the classifier_type (all in same order).
167 * If not, we have to create the missing ones.
168 */
169 if (aci_type == classifier_type) {
170 continue;
171 }
172
173 /*
174 * Need to instantiate the missing classifier types until we get to the same type as aci_type then we are back in sync to continue reclassification
175 */
176 while (classifier_type != aci_type) {
177 struct ecm_classifier_instance *naci;
178 DEBUG_TRACE("%p: Instantiate missing type: %d\n", ci, classifier_type);
179 DEBUG_ASSERT(classifier_type < ECM_CLASSIFIER_TYPES, "Algorithm bad");
180
181 naci = ecm_classifier_assign_classifier(ci, classifier_type);
182 if (!naci) {
183 full_reclassification = false;
184 } else {
185 naci->deref(naci);
186 }
187
188 classifier_type++;
189 }
190 }
191
192 /*
193 * Add missing types
194 */
195 for (; classifier_type < ECM_CLASSIFIER_TYPES; ++classifier_type) {
196 struct ecm_classifier_instance *naci;
197 DEBUG_TRACE("%p: Instantiate missing type: %d\n", ci, classifier_type);
198
199 naci = ecm_classifier_assign_classifier(ci, classifier_type);
200 if (!naci) {
201 full_reclassification = false;
202 } else {
203 naci->deref(naci);
204 }
205 }
206
207 DEBUG_TRACE("%p: reclassify done: %u\n", ci, full_reclassification);
208 return full_reclassification;
209}
210