Fix up ./ecm_classifier_default.c
Change-Id: I015108c11e496a6b22ee6cee83d3bb7559947cea
diff --git a/ecm_classifier_default.c b/ecm_classifier_default.c
index 863f49b..00fae51 100644
--- a/ecm_classifier_default.c
+++ b/ecm_classifier_default.c
@@ -385,6 +385,45 @@
ct = nf_ct_get(skb, &ctinfo);
+#ifdef CONFIG_NF_CONNTRACK_APPID
+ /* Cradlepoint
+ * Flow is beeing looked at by ips, if it's marked as so. Wait till classification
+ * is complete, before allowing acceleration.
+ */
+ if (ct == NULL) {
+ DEBUG_TRACE("%px: No conntrack found for packet. Not allowing accel.\n", cdii);
+ cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
+ goto return_response;
+ } else {
+ if ( ct->dpi_engine.enabled && (! ct->dpi_engine.ips_complete)) {
+ cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
+ DEBUG_TRACE("%px: DPI engine still classifying connection ips %d\n", cdii, ct->dpi_engine.ips_complete);
+ goto return_response;
+ }
+ }
+#endif
+
+#ifdef CONFIG_NETFILTER_CP_FLOWSTATS /* CP_LATENCY_IP*/
+#define CP_MAX_DECELERATED_PKTS 70
+/* Number of packets per flow to be processed in host CPU before giving control back to NSS*
+ * We picked 70 packets as a limit so we give enough time to capture a latency sample, without
+ * affecting performance.
+ */
+ if (cp_flowstats_enabled) {
+ if (cdii->protocol == IPPROTO_TCP) {
+ /* For TCP flows difer NSS acceleration till we have at least one sample or
+ * we wait till CP_MAX_DECELERATED_PKTS limit
+ */
+ if (ct && ((ct->proto.tcp.num_samples == 0) &&
+ (ct->packets_in + ct->packets_out) < CP_MAX_DECELERATED_PKTS)) {
+ DEBUG_TRACE("%px: Not enough packets for latency defering accel.\n", cdii);
+ cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
+ goto return_response;
+ }
+ }
+ }
+#endif //CONFIG_NETFILTER_CP_FLOWSTATS
+
/*
* Should we delay the acceleration?
*/
diff --git a/ecm_classifier_default.c.orig b/ecm_classifier_default.c.orig
deleted file mode 100644
index 863f49b..0000000
--- a/ecm_classifier_default.c.orig
+++ /dev/null
@@ -1,821 +0,0 @@
-/*
- **************************************************************************
- * Copyright (c) 2014-2016, 2020, The Linux Foundation. All rights reserved.
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all copies.
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- **************************************************************************
- */
-
-#include <linux/version.h>
-#include <linux/types.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/icmp.h>
-#include <linux/debugfs.h>
-#include <linux/kthread.h>
-#include <linux/pkt_sched.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <net/route.h>
-#include <net/ip.h>
-#include <net/tcp.h>
-#include <asm/unaligned.h>
-#include <asm/uaccess.h> /* for put_user */
-#include <net/ipv6.h>
-#include <linux/inet.h>
-#include <linux/in.h>
-#include <linux/udp.h>
-#include <linux/tcp.h>
-
-#include <linux/netfilter_ipv4.h>
-#include <linux/netfilter_bridge.h>
-#include <net/netfilter/nf_conntrack.h>
-#include <net/netfilter/nf_conntrack_helper.h>
-#include <net/netfilter/nf_conntrack_l4proto.h>
-#include <net/netfilter/nf_conntrack_core.h>
-#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
-#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
-
-/*
- * Debug output levels
- * 0 = OFF
- * 1 = ASSERTS / ERRORS
- * 2 = 1 + WARN
- * 3 = 2 + INFO
- * 4 = 3 + TRACE
- */
-#define DEBUG_LEVEL ECM_CLASSIFIER_DEFAULT_DEBUG_LEVEL
-
-#include "ecm_types.h"
-#include "ecm_db_types.h"
-#include "ecm_state.h"
-#include "ecm_tracker.h"
-#include "ecm_front_end_types.h"
-#include "ecm_classifier.h"
-#include "ecm_tracker_datagram.h"
-#include "ecm_tracker_udp.h"
-#include "ecm_tracker_tcp.h"
-#include "ecm_db.h"
-#include "ecm_classifier_default.h"
-
-/*
- * Magic numbers
- */
-#define ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC 0x8761
-#define ECM_CLASSIFIER_DEFAULT_STATE_FILE_INSTANCE_MAGIC 0x3321
-
-/*
- * struct ecm_classifier_default_internal_instance
- * State to allow tracking of dynamic priority for a connection
- */
-struct ecm_classifier_default_internal_instance {
- struct ecm_classifier_default_instance base; /* Base type */
-
- uint32_t ci_serial; /* RO: Serial of the connection */
- int protocol; /* RO: Protocol of the connection */
-
- struct ecm_classifier_process_response process_response;
- /* Last process response computed */
-
- ecm_db_timer_group_t timer_group; /* The timer group the connection should be in based on state */
-
- ecm_tracker_sender_type_t ingress_sender; /* RO: Which sender is sending ingress data */
- ecm_tracker_sender_type_t egress_sender; /* RO: Which sender is sending egress data */
-
- struct ecm_tracker_instance *ti; /* RO: Tracker used for state and timer group checking. Pointer will not change so safe to access outside of lock. */
-
- int refs; /* Integer to trap we never go negative */
-#if (DEBUG_LEVEL > 0)
- uint16_t magic;
-#endif
-};
-
-static DEFINE_SPINLOCK(ecm_classifier_default_lock); /* Concurrency control SMP access */
-static int ecm_classifier_default_count = 0; /* Tracks number of instances allocated */
-
-/*
- * Operational control
- */
-static ecm_classifier_acceleration_mode_t ecm_classifier_default_accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_ACCEL;
- /* Cause connections whose hosts are both on-link to be accelerated */
-static int ecm_classifier_default_enabled = 1; /* When disabled the qos algorithm will not be applied to skb's */
-
-/*
- * Management thread control
- */
-static bool ecm_classifier_default_terminate_pending = false; /* True when the user wants us to terminate */
-
-/*
- * Character device stuff - used to communicate status back to user space
- */
-#define ECM_CLASSIFIER_DEFAULT_STATE_FILE_BUFFER_SIZE 1024
-struct ecm_classifier_default_state_file_instance {
- struct ecm_classifier_default_internal_instance *cdii;
- bool doc_start_written;
- bool doc_end_written;
- char msg_buffer[ECM_CLASSIFIER_DEFAULT_STATE_FILE_BUFFER_SIZE]; /* Used to hold the current state message being output */
- char *msgp; /* Points into the msg buffer as we output it piece by piece */
- int msg_len; /* Length of the buffer still to be written out */
-#if (DEBUG_LEVEL > 0)
- uint16_t magic;
-#endif
-};
-static struct dentry *ecm_classifier_default_dentry; /* Debugfs dentry object */
-
-/*
- * _ecm_classifier_default_ref()
- * Ref
- */
-static void _ecm_classifier_default_ref(struct ecm_classifier_default_internal_instance *cdii)
-{
- cdii->refs++;
- DEBUG_TRACE("%px: cdii ref %d\n", cdii, cdii->refs);
- DEBUG_ASSERT(cdii->refs > 0, "%px: ref wrap\n", cdii);
-}
-
-/*
- * ecm_classifier_default_ref()
- * Ref
- */
-static void ecm_classifier_default_ref(struct ecm_classifier_instance *ci)
-{
- struct ecm_classifier_default_internal_instance *cdii;
- cdii = (struct ecm_classifier_default_internal_instance *)ci;
-
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
- spin_lock_bh(&ecm_classifier_default_lock);
- _ecm_classifier_default_ref(cdii);
- spin_unlock_bh(&ecm_classifier_default_lock);
-}
-
-/*
- * ecm_classifier_default_deref()
- * Deref
- */
-static int ecm_classifier_default_deref(struct ecm_classifier_instance *ci)
-{
- struct ecm_classifier_default_internal_instance *cdii;
- cdii = (struct ecm_classifier_default_internal_instance *)ci;
-
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
- spin_lock_bh(&ecm_classifier_default_lock);
- cdii->refs--;
- DEBUG_ASSERT(cdii->refs >= 0, "%px: refs wrapped\n", cdii);
- DEBUG_TRACE("%px: Default classifier deref %d\n", cdii, cdii->refs);
- if (cdii->refs) {
- int refs = cdii->refs;
- spin_unlock_bh(&ecm_classifier_default_lock);
- return refs;
- }
-
- /*
- * Object to be destroyed
- */
- ecm_classifier_default_count--;
- DEBUG_ASSERT(ecm_classifier_default_count >= 0, "%px: ecm_classifier_default_count wrap\n", cdii);
-
- spin_unlock_bh(&ecm_classifier_default_lock);
-
- /*
- * Release our tracker
- */
- cdii->ti->deref(cdii->ti);
-
- /*
- * Final
- */
- DEBUG_INFO("%px: Final default classifier instance\n", cdii);
- kfree(cdii);
-
- return 0;
-}
-
-/*
- * ecm_classifier_default_ready_for_accel()
- * Checks if the connection is ready for the acceleration.
- *
- * This function is called, if the acceleration delay feature is enabled.
- */
-static bool ecm_classifier_default_ready_for_accel(
- struct ecm_classifier_default_internal_instance *cdii,
- struct nf_conn *ct, enum ip_conntrack_info ctinfo,
- ecm_tracker_connection_state_t prevailing_state)
-{
- int slow_pkts;
- struct ecm_db_connection_instance *ci;
- struct ecm_front_end_connection_instance *feci;
-
- /*
- * Delay forever until seeing the reply packet.
- */
- if (ecm_classifier_accel_delay_pkts == 1) {
- if (!ct) {
- /*
- * Conntrack is NULL. We need to check the state of ECM tracker.
- */
- if (unlikely(prevailing_state != ECM_TRACKER_CONNECTION_STATE_ESTABLISHED)) {
- /*
- * Tracker hasn't been in established state yet.
- * Connection is not ready for the acceleration.
- */
- return false;
- }
-
- /*
- * The ECM connection's tracker is in establish state,
- * so the connection is ready for the acceleration.
- */
- return true;
- }
-
- /*
- * If TCP is in established state, connection is ready for acceleration.
- */
- if (cdii->protocol == IPPROTO_TCP) {
- uint8_t state;
- spin_lock_bh(&ct->lock);
- state = ct->proto.tcp.state;
- if (state != TCP_CONNTRACK_ESTABLISHED) {
- spin_unlock_bh(&ct->lock);
- DEBUG_TRACE("%px: Connection in termination state %#X\n", cdii, state);
- return false;
- }
- spin_unlock_bh(&ct->lock);
-
- return true;
- }
-
- /*
- * For non-TCP connections, we check the conntrack establish state.
- */
- if ((ctinfo != IP_CT_ESTABLISHED) && (ctinfo != IP_CT_ESTABLISHED_REPLY)) {
- DEBUG_INFO("%px: Connection is not established", cdii);
- return false;
- }
-
- /*
- * Non-TCP connection's conntarck is in established state.
- * The connection is ready for acceleration.
- */
- return true;
- }
-
- /*
- * Delay the acceleration until we see <N> number of packets.
- * ecm_classifier_accel_delay_pkts = <N>
- */
- ci = ecm_db_connection_serial_find_and_ref(cdii->ci_serial);
- if (!ci) {
- DEBUG_TRACE("%px: No ci found for %u\n", cdii, cdii->ci_serial);
- return false;
- }
-
- /*
- * Get the packet count we have seen in the slow path so far.
- */
- feci = ecm_db_connection_front_end_get_and_ref(ci);
-
- spin_lock_bh(&feci->lock);
- slow_pkts = feci->stats.slow_path_packets;
- spin_unlock_bh(&feci->lock);
-
- feci->deref(feci);
- ecm_db_connection_deref(ci);
-
- /*
- * Check if we have seen slow path packets as the predefined count.
- */
- if (slow_pkts < ecm_classifier_accel_delay_pkts) {
- DEBUG_TRACE("%px: delay the acceleration: slow packets: %d default delay packet count: %d\n",
- cdii, slow_pkts, ecm_classifier_accel_delay_pkts);
-
- /*
- * We haven't reached the slow path packet limit.
- * We can wait more to accelerate the connection.
- */
- return false;
- }
-
- /*
- * We waited enough time for the acceleration, we can allow it now.
- */
- return true;
-}
-
-/*
- * ecm_classifier_default_process_callback()
- * Process new data updating the priority
- *
- * NOTE: This function would only ever be called if all other classifiers have failed.
- */
-static void ecm_classifier_default_process(struct ecm_classifier_instance *aci, ecm_tracker_sender_type_t sender,
- struct ecm_tracker_ip_header *ip_hdr, struct sk_buff *skb,
- struct ecm_classifier_process_response *process_response)
-{
- struct ecm_tracker_instance *ti;
- ecm_tracker_sender_state_t from_state;
- ecm_tracker_sender_state_t to_state;
- ecm_tracker_connection_state_t prevailing_state;
- ecm_db_timer_group_t tg;
- struct ecm_classifier_default_internal_instance *cdii = (struct ecm_classifier_default_internal_instance *)aci;
- struct nf_conn *ct;
- enum ip_conntrack_info ctinfo;
-
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: invalid state magic\n", cdii);
-
- /*
- * Get qos result and accel mode
- * Default classifier is rarely disabled.
- */
- if (unlikely(!ecm_classifier_default_enabled)) {
- /*
- * Still relevant but have no actions that need processing
- */
- spin_lock_bh(&ecm_classifier_default_lock);
- cdii->process_response.process_actions = 0;
- *process_response = cdii->process_response;
- spin_unlock_bh(&ecm_classifier_default_lock);
- return;
- }
-
- /*
- * Update connection state
- * Compute the timer group this connection should be in.
- * For this we need the tracker and the state to be updated.
- * NOTE: Tracker does not need to be ref'd it will exist for as long as this default classifier instance does
- * which is at least for the duration of this call.
- */
- ti = cdii->ti;
- ti->state_update(ti, sender, ip_hdr, skb);
- ti->state_get(ti, &from_state, &to_state, &prevailing_state, &tg);
- spin_lock_bh(&ecm_classifier_default_lock);
- if (unlikely(cdii->timer_group != tg)) {
- /*
- * Timer group has changed
- */
- cdii->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_TIMER_GROUP;
- cdii->process_response.timer_group = tg;
-
- /*
- * Record for future change comparisons
- */
- cdii->timer_group = tg;
- }
-
- /*
- * Accel?
- */
- if (ecm_classifier_default_accel_mode != ECM_CLASSIFIER_ACCELERATION_MODE_DONT_CARE) {
- cdii->process_response.accel_mode = ecm_classifier_default_accel_mode;
- cdii->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
- } else {
- cdii->process_response.process_actions &= ~ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
- }
- spin_unlock_bh(&ecm_classifier_default_lock);
-
- ct = nf_ct_get(skb, &ctinfo);
-
- /*
- * Should we delay the acceleration?
- */
- if (ecm_classifier_accel_delay_pkts) {
- bool ret;
-
- ret = ecm_classifier_default_ready_for_accel(cdii, ct, ctinfo, prevailing_state);
- if (ret) {
- goto return_response;
- }
- goto accel_no;
- }
-
- /*
- * Acceleration delay is disabled. So, handle the flows as they are.
- * Handle non-TCP case
- */
- if (cdii->protocol != IPPROTO_TCP) {
- if (unlikely(prevailing_state != ECM_TRACKER_CONNECTION_STATE_ESTABLISHED)) {
- goto accel_no;
- }
- goto return_response;
- }
-
- /*
- * Check the TCP connection state, when the ct is NULL.
- * ct valid case was already checked in the ecm_nss{sfe}_ported_ipv4{6}_process functions.
- * If we are not established then we deny acceleration.
- */
- if (!ct) {
- DEBUG_TRACE("%px: No Conntrack found for packet, using ECM tracker state\n", cdii);
-
- if ((prevailing_state == ECM_TRACKER_CONNECTION_STATE_FAULT) || (prevailing_state == ECM_TRACKER_CONNECTION_STATE_CLOSED)) {
- cdii->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_TIMER_GROUP_NO_TOUCH;
- }
-
- if (unlikely(prevailing_state != ECM_TRACKER_CONNECTION_STATE_ESTABLISHED)) {
- goto accel_no;
- }
- } else {
- /*
- * If the connection is shutting down do not manage it.
- * state can not be SYN_SENT, SYN_RECV because connection is assured
- * Not managed states: FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE.
- */
- spin_lock_bh(&ct->lock);
- if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) {
- spin_unlock_bh(&ct->lock);
- DEBUG_TRACE("%px: Connection in termination state %#X\n", ct, ct->proto.tcp.state);
- goto accel_no;
- }
- spin_unlock_bh(&ct->lock);
- }
-
-return_response:
- /*
- * Return the process response
- */
- spin_lock_bh(&ecm_classifier_default_lock);
- *process_response = cdii->process_response;
- spin_unlock_bh(&ecm_classifier_default_lock);
- return;
-
-accel_no:
- spin_lock_bh(&ecm_classifier_default_lock);
- cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
- *process_response = cdii->process_response;
- spin_unlock_bh(&ecm_classifier_default_lock);
-}
-
-/*
- * ecm_classifier_default_type_get()
- * Get type of classifier this is
- */
-static ecm_classifier_type_t ecm_classifier_default_type_get(struct ecm_classifier_instance *aci)
-{
- struct ecm_classifier_default_internal_instance *cdii;
- cdii = (struct ecm_classifier_default_internal_instance *)aci;
-
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
- return ECM_CLASSIFIER_TYPE_DEFAULT;
-}
-
-/*
- * ecm_classifier_default_reclassify_allowed()
- * Get whether reclassification is allowed
- */
-static bool ecm_classifier_default_reclassify_allowed(struct ecm_classifier_instance *aci)
-{
- struct ecm_classifier_default_internal_instance *cdii;
- cdii = (struct ecm_classifier_default_internal_instance *)aci;
-
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
- return true;
-}
-
-/*
- * ecm_classifier_default_reclassify()
- * Reclassify
- */
-static void ecm_classifier_default_reclassify(struct ecm_classifier_instance *aci)
-{
- struct ecm_classifier_default_internal_instance *cdii;
- cdii = (struct ecm_classifier_default_internal_instance *)aci;
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
-}
-
-/*
- * ecm_classifier_default_last_process_response_get()
- * Get result code returned by the last process call
- */
-static void ecm_classifier_default_last_process_response_get(struct ecm_classifier_instance *aci,
- struct ecm_classifier_process_response *process_response)
-{
- struct ecm_classifier_default_internal_instance *cdii;
- cdii = (struct ecm_classifier_default_internal_instance *)aci;
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
-
- spin_lock_bh(&ecm_classifier_default_lock);
- *process_response = cdii->process_response;
- spin_unlock_bh(&ecm_classifier_default_lock);
-}
-
-/*
- * ecm_classifier_default_sync_to_v4()
- * Front end is pushing accel engine state to us
- */
-static void ecm_classifier_default_sync_to_v4(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_sync *sync)
-{
- struct ecm_classifier_default_internal_instance *cdii __attribute__((unused));
-
- cdii = (struct ecm_classifier_default_internal_instance *)aci;
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
-}
-
-/*
- * ecm_classifier_default_sync_from_v4()
- * Front end is retrieving accel engine state from us
- */
-static void ecm_classifier_default_sync_from_v4(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_create *ecrc)
-{
- struct ecm_classifier_default_internal_instance *cdii __attribute__((unused));
-
- cdii = (struct ecm_classifier_default_internal_instance *)aci;
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
-}
-
-/*
- * ecm_classifier_default_sync_to_v6()
- * Front end is pushing accel engine state to us
- */
-static void ecm_classifier_default_sync_to_v6(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_sync *sync)
-{
- struct ecm_classifier_default_internal_instance *cdii __attribute__((unused));
-
- cdii = (struct ecm_classifier_default_internal_instance *)aci;
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
-}
-
-/*
- * ecm_classifier_default_sync_from_v6()
- * Front end is retrieving accel engine state from us
- */
-static void ecm_classifier_default_sync_from_v6(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_create *ecrc)
-{
- struct ecm_classifier_default_internal_instance *cdii __attribute__((unused));
-
- cdii = (struct ecm_classifier_default_internal_instance *)aci;
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
-}
-
-/*
- * ecm_classifier_tracker_get_and_ref()
- * Obtain default classifiers tracker (usually for state tracking for the connection as it always exists for the connection)
- */
-static struct ecm_tracker_instance *ecm_classifier_tracker_get_and_ref(struct ecm_classifier_default_instance *dci)
-{
- struct ecm_classifier_default_internal_instance *cdii;
- struct ecm_tracker_instance *ti;
-
- cdii = (struct ecm_classifier_default_internal_instance *)dci;
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
-
- ti = cdii->ti;
- ti->ref(ti);
- return ti;
-}
-
-#ifdef ECM_STATE_OUTPUT_ENABLE
-/*
- * ecm_classifier_default_state_get()
- * Return state
- */
-static int ecm_classifier_default_state_get(struct ecm_classifier_instance *ci, struct ecm_state_file_instance *sfi)
-{
- int result;
- struct ecm_classifier_default_internal_instance *cdii;
- struct ecm_classifier_process_response process_response;
- ecm_db_timer_group_t timer_group;
- ecm_tracker_sender_type_t ingress_sender;
- ecm_tracker_sender_type_t egress_sender;
-
- cdii = (struct ecm_classifier_default_internal_instance *)ci;
- DEBUG_CHECK_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC, "%px: magic failed", cdii);
-
- if ((result = ecm_state_prefix_add(sfi, "default"))) {
- return result;
- }
-
- spin_lock_bh(&ecm_classifier_default_lock);
- egress_sender = cdii->egress_sender;
- ingress_sender = cdii->ingress_sender;
- timer_group = cdii->timer_group;
- process_response = cdii->process_response;
- spin_unlock_bh(&ecm_classifier_default_lock);
-
- if ((result = ecm_state_write(sfi, "ingress_sender", "%d", ingress_sender))) {
- return result;
- }
- if ((result = ecm_state_write(sfi, "egress_sender", "%d", egress_sender))) {
- return result;
- }
- if ((result = ecm_state_write(sfi, "timer_group", "%d", timer_group))) {
- return result;
- }
- if ((result = ecm_state_write(sfi, "accel_delay_pkt_default", "%d", ecm_classifier_accel_delay_pkts))) {
- return result;
- }
-
- /*
- * Output our last process response
- */
- if ((result = ecm_classifier_process_response_state_get(sfi, &process_response))) {
- return result;
- }
-
- if ((result = ecm_state_prefix_add(sfi, "trackers"))) {
- return result;
- }
-
- /*
- * Output our tracker state
- */
- if ((result = cdii->ti->state_text_get(cdii->ti, sfi))) {
- return result;
- }
-
- if ((result = ecm_state_prefix_remove(sfi))) {
- return result;
- }
-
- return ecm_state_prefix_remove(sfi);
-}
-#endif
-
-/*
- * ecm_classifier_default_instance_alloc()
- * Allocate an instance of the default classifier
- */
-struct ecm_classifier_default_instance *ecm_classifier_default_instance_alloc(struct ecm_db_connection_instance *ci, int protocol, ecm_db_direction_t dir, int from_port, int to_port)
-{
- struct ecm_classifier_default_internal_instance *cdii;
- struct ecm_classifier_default_instance *cdi;
-
- /*
- * Allocate the instance
- */
- cdii = (struct ecm_classifier_default_internal_instance *)kzalloc(sizeof(struct ecm_classifier_default_internal_instance), GFP_ATOMIC | __GFP_NOWARN);
- if (!cdii) {
- DEBUG_WARN("Failed to allocate default instance\n");
- return NULL;
- }
-
- /*
- * Allocate a tracker for state etc.
- */
- if (protocol == IPPROTO_TCP) {
- DEBUG_TRACE("%px: Alloc tracker for TCP connection: %px\n", cdii, ci);
- cdii->ti = (struct ecm_tracker_instance *)ecm_tracker_tcp_alloc();
- if (!cdii->ti) {
- DEBUG_WARN("%px: Failed to alloc tracker\n", cdii);
- kfree(cdii);
- return NULL;
- }
- ecm_tracker_tcp_init((struct ecm_tracker_tcp_instance *)cdii->ti, ECM_TRACKER_CONNECTION_TRACKING_LIMIT_DEFAULT, 1500, 1500);
- } else if (protocol == IPPROTO_UDP) {
- DEBUG_TRACE("%px: Alloc tracker for UDP connection: %px\n", cdii, ci);
- cdii->ti = (struct ecm_tracker_instance *)ecm_tracker_udp_alloc();
- if (!cdii->ti) {
- DEBUG_WARN("%px: Failed to alloc tracker\n", cdii);
- kfree(cdii);
- return NULL;
- }
- ecm_tracker_udp_init((struct ecm_tracker_udp_instance *)cdii->ti, ECM_TRACKER_CONNECTION_TRACKING_LIMIT_DEFAULT, from_port, to_port);
- } else {
- DEBUG_TRACE("%px: Alloc tracker for non-ported connection: %px\n", cdii, ci);
- cdii->ti = (struct ecm_tracker_instance *)ecm_tracker_datagram_alloc();
- if (!cdii->ti) {
- DEBUG_WARN("%px: Failed to alloc tracker\n", cdii);
- kfree(cdii);
- return NULL;
- }
- ecm_tracker_datagram_init((struct ecm_tracker_datagram_instance *)cdii->ti, ECM_TRACKER_CONNECTION_TRACKING_LIMIT_DEFAULT);
- }
-
- DEBUG_SET_MAGIC(cdii, ECM_CLASSIFIER_DEFAULT_INTERNAL_INSTANCE_MAGIC);
- cdii->refs = 1;
- cdii->ci_serial = ecm_db_connection_serial_get(ci);
- cdii->protocol = protocol;
-
- /*
- * We are always relevant to the connection
- */
- cdii->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
-
- /*
- * Using the connection direction identify egress and ingress host addresses
- */
- if (dir == ECM_DB_DIRECTION_INGRESS_NAT) {
- cdii->ingress_sender = ECM_TRACKER_SENDER_TYPE_SRC;
- cdii->egress_sender = ECM_TRACKER_SENDER_TYPE_DEST;
- } else {
- cdii->egress_sender = ECM_TRACKER_SENDER_TYPE_SRC;
- cdii->ingress_sender = ECM_TRACKER_SENDER_TYPE_DEST;
- }
- DEBUG_TRACE("%px: Ingress sender = %d egress sender = %d\n", cdii, cdii->ingress_sender, cdii->egress_sender);
-
- /*
- * Methods specific to the default classifier
- */
- cdi = (struct ecm_classifier_default_instance *)cdii;
- cdi->tracker_get_and_ref = ecm_classifier_tracker_get_and_ref;
-
- /*
- * Methods generic to all classifiers.
- */
- cdi->base.process = ecm_classifier_default_process;
- cdi->base.sync_from_v4 = ecm_classifier_default_sync_from_v4;
- cdi->base.sync_to_v4 = ecm_classifier_default_sync_to_v4;
- cdi->base.sync_from_v6 = ecm_classifier_default_sync_from_v6;
- cdi->base.sync_to_v6 = ecm_classifier_default_sync_to_v6;
- cdi->base.type_get = ecm_classifier_default_type_get;
- cdi->base.reclassify_allowed = ecm_classifier_default_reclassify_allowed;
- cdi->base.reclassify = ecm_classifier_default_reclassify;
- cdi->base.last_process_response_get = ecm_classifier_default_last_process_response_get;
-#ifdef ECM_STATE_OUTPUT_ENABLE
- cdi->base.state_get = ecm_classifier_default_state_get;
-#endif
- cdi->base.ref = ecm_classifier_default_ref;
- cdi->base.deref = ecm_classifier_default_deref;
-
- spin_lock_bh(&ecm_classifier_default_lock);
-
- /*
- * Final check if we are pending termination
- */
- if (ecm_classifier_default_terminate_pending) {
- spin_unlock_bh(&ecm_classifier_default_lock);
- DEBUG_INFO("%px: Terminating\n", ci);
- cdii->ti->deref(cdii->ti);
- kfree(cdii);
- return NULL;
- }
-
- /*
- * Increment stats
- */
- ecm_classifier_default_count++;
- DEBUG_ASSERT(ecm_classifier_default_count > 0, "%px: ecm_classifier_default_count wrap\n", cdii);
- spin_unlock_bh(&ecm_classifier_default_lock);
-
- DEBUG_INFO("Default classifier instance alloc: %px\n", cdii);
- return cdi;
-}
-EXPORT_SYMBOL(ecm_classifier_default_instance_alloc);
-
-/*
- * ecm_classifier_default_init()
- */
-int ecm_classifier_default_init(struct dentry *dentry)
-{
- DEBUG_INFO("Default classifier Module init\n");
-
- DEBUG_ASSERT(ECM_CLASSIFIER_TYPE_DEFAULT == 0, "DO NOT CHANGE DEFAULT PRIORITY");
-
- ecm_classifier_default_dentry = debugfs_create_dir("ecm_classifier_default", dentry);
- if (!ecm_classifier_default_dentry) {
- DEBUG_ERROR("Failed to create ecm default classifier directory in debugfs\n");
- return -1;
- }
-
- if (!debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_default_dentry,
- (u32 *)&ecm_classifier_default_enabled)) {
- DEBUG_ERROR("Failed to create ecm deafult classifier enabled file in debugfs\n");
- debugfs_remove_recursive(ecm_classifier_default_dentry);
- return -1;
- }
-
- if (!debugfs_create_u32("accel_mode", S_IRUGO | S_IWUSR, ecm_classifier_default_dentry,
- (u32 *)&ecm_classifier_default_accel_mode)) {
- DEBUG_ERROR("Failed to create ecm deafult classifier accel_mode file in debugfs\n");
- debugfs_remove_recursive(ecm_classifier_default_dentry);
- return -1;
- }
-
- if (!debugfs_create_u32("accel_delay_pkts", S_IRUGO | S_IWUSR, ecm_classifier_default_dentry,
- (u32 *)&ecm_classifier_accel_delay_pkts)) {
- DEBUG_ERROR("Failed to create accel delay packet counts in debugfs\n");
- debugfs_remove_recursive(ecm_classifier_default_dentry);
- return -1;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(ecm_classifier_default_init);
-
-/*
- * ecm_classifier_default_exit()
- */
-void ecm_classifier_default_exit(void)
-{
- DEBUG_INFO("Default classifier Module exit\n");
- spin_lock_bh(&ecm_classifier_default_lock);
- ecm_classifier_default_terminate_pending = true;
- spin_unlock_bh(&ecm_classifier_default_lock);
-
- /*
- * Remove the debugfs files recursively.
- */
- if (ecm_classifier_default_dentry) {
- debugfs_remove_recursive(ecm_classifier_default_dentry);
- }
-}
-EXPORT_SYMBOL(ecm_classifier_default_exit);
diff --git a/ecm_classifier_default.c.rej b/ecm_classifier_default.c.rej
deleted file mode 100644
index 9b29d5b..0000000
--- a/ecm_classifier_default.c.rej
+++ /dev/null
@@ -1,65 +0,0 @@
---- ecm_classifier_default.c
-+++ ecm_classifier_default.c
-@@ -272,10 +272,50 @@ static void ecm_classifier_default_process(struct ecm_classifier_instance *aci,
- */
- cdii->timer_group = tg;
- }
- spin_unlock_bh(&ecm_classifier_default_lock);
-
-+ /* Cradlepoint
-+ * Flow is beeing looked at by ips, if it's marked as so. Wait till classification
-+ * is complete, before allowing acceleration.
-+ */
-+ ct = nf_ct_get(skb, &ctinfo);
-+#ifdef CONFIG_NF_CONNTRACK_APPID
-+ if (ct == NULL) {
-+ DEBUG_TRACE("%p: No conntrack found for packet. Not allowing accel.\n", cdii);
-+ cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
-+ goto return_response;
-+ } else {
-+ if ( ct->dpi_engine.enabled && (! ct->dpi_engine.ips_complete)) {
-+ cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
-+ DEBUG_TRACE("%p: DPI engine still classifying connection ips %d\n", cdii, ct->dpi_engine.ips_complete);
-+ goto return_response;
-+ }
-+ }
-+#endif
-+#ifdef CONFIG_NETFILTER_CP_FLOWSTATS /* CP_LATENCY_IP*/
-+#define CP_MAX_DECELERATED_PKTS 70
-+/* Number of packets per flow to be processed in host CPU before giving control back to NSS*
-+ * We picked 70 packets as a limit so we give enough time to capture a latency sample, without
-+ * affecting performance.
-+ */
-+ if (cp_flowstats_enabled) {
-+ if (cdii->protocol == IPPROTO_TCP) {
-+ /* For TCP flows difer NSS acceleration till we have at least one sample or
-+ * we wait till CP_MAX_DECELERATED_PKTS limit
-+ */
-+ if (ct && ((ct->proto.tcp.num_samples == 0) &&
-+ (ct->packets_in + ct->packets_out) < CP_MAX_DECELERATED_PKTS)) {
-+ DEBUG_TRACE("%p: Not enough packets for latency defering accel.\n", cdii);
-+ cdii->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
-+ goto return_response;
-+ }
-+ }
-+}
-+#endif //CONFIG_NETFILTER_CP_FLOWSTATS
-+
-+
- /*
- * Handle non-TCP case
- */
- if (cdii->protocol != IPPROTO_TCP) {
- if (unlikely(prevailing_state != ECM_TRACKER_CONNECTION_STATE_ESTABLISHED)) {
-@@ -287,11 +327,10 @@ static void ecm_classifier_default_process(struct ecm_classifier_instance *aci,
- /*
- * Check the TCP connection state, when the ct is NULL.
- * ct valid case was already checked in the ecm_nss{sfe}_ported_ipv4{6}_process functions.
- * If we are not established then we deny acceleration.
- */
-- ct = nf_ct_get(skb, &ctinfo);
- if (!ct) {
- DEBUG_TRACE("%p: No Conntrack found for packet, using ECM tracker state\n", cdii);
-
- if ((prevailing_state == ECM_TRACKER_CONNECTION_STATE_FAULT) || (prevailing_state == ECM_TRACKER_CONNECTION_STATE_CLOSED)) {
- cdii->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_TIMER_GROUP_NO_TOUCH;