/*
 **************************************************************************
 * 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 <nss_api_if.h>

extern int ecm_nss_ipv6_no_action_limit_default;		/* Default no-action limit. */
extern int ecm_nss_ipv6_driver_fail_limit_default;		/* Default driver fail limit. */
extern int ecm_nss_ipv6_nack_limit_default;			/* Default nack limit. */
extern int ecm_nss_ipv6_accelerated_count;			/* Total offloads */
extern int ecm_nss_ipv6_pending_accel_count;			/* Total pending offloads issued to the NSS / awaiting completion */
extern int ecm_nss_ipv6_pending_decel_count;			/* Total pending deceleration requests issued to the NSS / awaiting completion */

/*
 * Limiting the acceleration of connections.
 *
 * By default there is no acceleration limiting.
 * This means that when ECM has more connections (that can be accelerated) than the acceleration
 * engine will allow the ECM will continue to try to accelerate.
 * In this scenario the acceleration engine will begin removal of existing rules to make way for new ones.
 * When the accel_limit_mode is set to FIXED ECM will not permit more rules to be issued than the engine will allow.
 */
extern uint32_t ecm_nss_ipv6_accel_limit_mode;

/*
 * Flag to enable/disable bridge VLAN passthrough feature.
 * By default this feature is disabled.
 */
extern int ecm_nss_ipv6_vlan_passthrough_enable;

/*
 * Locking of the classifier - concurrency control for file global parameters.
 * NOTE: It is safe to take this lock WHILE HOLDING a feci->lock.  The reverse is NOT SAFE.
 */
extern spinlock_t ecm_nss_ipv6_lock;			/* Protect against SMP access between netfilter, events and private threaded function. */

/*
 * NSS driver linkage
 */
extern struct nss_ctx_instance *ecm_nss_ipv6_nss_ipv6_mgr;

/*
 * ecm_nss_ipv6_accel_pending_set()
 *	Set pending acceleration for the connection object.
 *
 * Return false if the acceleration is not permitted or is already in progress.
 */
static inline bool ecm_nss_ipv6_accel_pending_set(struct ecm_front_end_connection_instance *feci)
{
	DEBUG_INFO("%px: Accel conn: %px\n", feci, feci->ci);

	/*
	 * If re-generation is required then we cannot permit acceleration
	 */
	if (ecm_db_connection_regeneration_required_peek(feci->ci)) {
		DEBUG_TRACE("%px: accel %px failed - regen required\n", feci, feci->ci);
		return false;
	}

	/*
	 * Is connection acceleration permanently failed?
	 */
	spin_lock_bh(&feci->lock);
	if (ECM_FRONT_END_ACCELERATION_FAILED(feci->accel_mode)) {
		spin_unlock_bh(&feci->lock);
		DEBUG_TRACE("%px: accel %px failed\n", feci, feci->ci);
		return false;
	}

	/*
	 * If acceleration mode is anything other than "not accelerated" then ignore.
	 */
	if (feci->accel_mode != ECM_FRONT_END_ACCELERATION_MODE_DECEL) {
		spin_unlock_bh(&feci->lock);
		DEBUG_TRACE("%px: Ignoring wrong mode accel for conn: %px\n", feci, feci->ci);
		return false;
	}

	/*
	 * Do we have a fixed upper limit for acceleration?
	 */
	spin_lock_bh(&ecm_nss_ipv6_lock);
	if (ecm_nss_ipv6_accel_limit_mode & ECM_FRONT_END_ACCEL_LIMIT_MODE_FIXED) {
		if ((ecm_nss_ipv6_pending_accel_count + ecm_nss_ipv6_accelerated_count) >= nss_ipv6_max_conn_count()) {
			spin_unlock_bh(&ecm_nss_ipv6_lock);
			spin_unlock_bh(&feci->lock);
			DEBUG_INFO("%px: Accel limit reached, accel denied: %px\n", feci, feci->ci);
			return false;
		}
	}

	/*
	 * Okay to accelerate
	 */
	ecm_nss_ipv6_pending_accel_count++;
	spin_unlock_bh(&ecm_nss_ipv6_lock);

	/*
	 * Okay connection can be set to pending acceleration
	 */
	feci->accel_mode = ECM_FRONT_END_ACCELERATION_MODE_ACCEL_PENDING;
	spin_unlock_bh(&feci->lock);
	return true;
}

/*
 * _ecm_nss_ipv6_accel_pending_clear()
 *	Clear pending acceleration for the connection object, setting it to the desired state.
 *
 * Returns true if "decelerate was pending".
 *
 * The feci->lock AND ecm_nss_ipv6_lock must be held on entry.
 */
static inline bool _ecm_nss_ipv6_accel_pending_clear(struct ecm_front_end_connection_instance *feci, ecm_front_end_acceleration_mode_t mode)
{
	bool decel_pending;

	/*
	 * Set the mode away from its accel pending state.
	 */
	DEBUG_ASSERT(feci->accel_mode == ECM_FRONT_END_ACCELERATION_MODE_ACCEL_PENDING, "%px: Accel mode unexpected: %d\n", feci, feci->accel_mode);
	feci->accel_mode = mode;

	/*
	 * Clear decelerate pending flag.
	 * This flag is only set when we are ACCEL_PENDING -
	 * and we are moving from that to the given mode anyway.
	 */
	decel_pending = feci->stats.decelerate_pending;
	feci->stats.decelerate_pending = false;

	/*
	 * Decrement pending counter
	 */
	ecm_nss_ipv6_pending_accel_count--;
	DEBUG_ASSERT(ecm_nss_ipv6_pending_accel_count >= 0, "Accel pending underflow\n");
	return decel_pending;
}

/*
 * ecm_nss_ipv6_accel_pending_clear()
 *	Clear pending acceleration for the connection object, setting it to the desired state.
 */
static inline bool ecm_nss_ipv6_accel_pending_clear(struct ecm_front_end_connection_instance *feci, ecm_front_end_acceleration_mode_t mode)
{
	bool decel_pending;
	spin_lock_bh(&feci->lock);
	spin_lock_bh(&ecm_nss_ipv6_lock);
	decel_pending = _ecm_nss_ipv6_accel_pending_clear(feci, mode);
	spin_unlock_bh(&ecm_nss_ipv6_lock);
	spin_unlock_bh(&feci->lock);
	return decel_pending;
}

extern void ecm_nss_ipv6_accel_done_time_update(struct ecm_front_end_connection_instance *feci);
extern void ecm_nss_ipv6_decel_done_time_update(struct ecm_front_end_connection_instance *feci);
extern int ecm_nss_ipv6_init(struct dentry *dentry);
extern void ecm_nss_ipv6_exit(void);
