/*
 **************************************************************************
 * Copyright (c) 2019-2021, 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.
 **************************************************************************
 */

/*
 * OVS Classifier.
 * This classifier is called for the connections which are created
 * on OVS interfaces. The connections can be routed or bridged connections.
 * The classifier processes these connection flows and decides if the connection
 * is ready to be accelerated. Moreover, it has an interface to an external classifier
 * to make smart decisions on the flows, such as extracting the VLAN information from the
 * OVS flow tables and gives it to the ECM front end to be passed to the acceleration engine.
 */
#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/debugfs.h>
#include <linux/ctype.h>
#include <net/tcp.h>
#include <net/ipv6.h>
#include <linux/inet.h>
#include <linux/in.h>
#include <linux/etherdevice.h>
#include <linux/netfilter/xt_dscp.h>

/*
 * Debug output levels
 * 0 = OFF
 * 1 = ASSERTS / ERRORS
 * 2 = 1 + WARN
 * 3 = 2 + INFO
 * 4 = 3 + TRACE
 */
#define DEBUG_LEVEL ECM_CLASSIFIER_OVS_DEBUG_LEVEL

#include <ovsmgr.h>
#include "ecm_types.h"
#include "ecm_db_types.h"
#include "ecm_state.h"
#include "ecm_tracker.h"
#include "ecm_classifier.h"
#include "ecm_front_end_types.h"
#include "ecm_tracker_datagram.h"
#include "ecm_tracker_udp.h"
#include "ecm_tracker_tcp.h"
#include "ecm_db.h"
#include "ecm_classifier_ovs.h"
#include "ecm_classifier_ovs_public.h"
#include "ecm_front_end_common.h"
#include "ecm_front_end_ipv4.h"
#ifdef ECM_IPV6_ENABLE
#include "ecm_front_end_ipv6.h"
#endif
#include "ecm_interface.h"

/*
 * Magic numbers
 */
#define ECM_CLASSIFIER_OVS_INSTANCE_MAGIC 0x2568

/*
 * struct ecm_classifier_ovs_instance
 * 	State per connection for OVS classifier
 */
struct ecm_classifier_ovs_instance {
	struct ecm_classifier_instance base;			/* Base type */

	uint32_t ci_serial;					/* RO: Serial of the connection */

	struct ecm_classifier_ovs_instance *next;		/* Next classifier state instance (for accouting and reporting purposes) */
	struct ecm_classifier_ovs_instance *prev;		/* Next classifier state instance (for accouting and reporting purposes) */

	struct ecm_classifier_process_response process_response;
								/* Last process response computed */
	int refs;						/* Integer to trap we never go negative */
#if (DEBUG_LEVEL > 0)
	uint16_t magic;
#endif
};

/*
 * Operational control.
 */
static int ecm_classifier_ovs_enabled = 1;			/* Operational behaviour */

/*
 * Management thread control
 */
static bool ecm_classifier_ovs_terminate_pending;	/* True when the user wants us to terminate */

/*
 * Debugfs dentry object.
 */
static struct dentry *ecm_classifier_ovs_dentry;

/*
 * Locking of the classifier structures
 */
static DEFINE_SPINLOCK(ecm_classifier_ovs_lock);			/* Protect SMP access. */

/*
 * List of our classifier instances
 */
static struct ecm_classifier_ovs_instance *ecm_classifier_ovs_instances = NULL;
								/* list of all active instances */
static int ecm_classifier_ovs_count = 0;			/* Tracks number of instances allocated */

/*
 * Callback object.
 */
static struct ecm_classifier_ovs_callbacks ovs;

/*
 * ecm_classifier_ovs_ref()
 *	Ref
 */
static void ecm_classifier_ovs_ref(struct ecm_classifier_instance *ci)
{
	struct ecm_classifier_ovs_instance *ecvi;
	ecvi = (struct ecm_classifier_ovs_instance *)ci;

	DEBUG_CHECK_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC, "%px: magic failed", ecvi);
	spin_lock_bh(&ecm_classifier_ovs_lock);
	ecvi->refs++;
	DEBUG_ASSERT(ecvi->refs > 0, "%px: ref wrap\n", ecvi);
	DEBUG_TRACE("%px: ecvi ref %d\n", ecvi, ecvi->refs);
	spin_unlock_bh(&ecm_classifier_ovs_lock);
}

/*
 * ecm_classifier_ovs_deref()
 *	Deref
 */
static int ecm_classifier_ovs_deref(struct ecm_classifier_instance *ci)
{
	struct ecm_classifier_ovs_instance *ecvi;
	ecvi = (struct ecm_classifier_ovs_instance *)ci;

	DEBUG_CHECK_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC, "%px: magic failed", ecvi);
	spin_lock_bh(&ecm_classifier_ovs_lock);
	ecvi->refs--;
	DEBUG_ASSERT(ecvi->refs >= 0, "%px: refs wrapped\n", ecvi);
	DEBUG_TRACE("%px: ecvi deref %d\n", ecvi, ecvi->refs);
	if (ecvi->refs) {
		int refs = ecvi->refs;
		spin_unlock_bh(&ecm_classifier_ovs_lock);
		return refs;
	}

	/*
	 * Object to be destroyed
	 */
	ecm_classifier_ovs_count--;
	DEBUG_ASSERT(ecm_classifier_ovs_count >= 0, "%px: ecm_classifier_ovs_count wrap\n", ecvi);

	/*
	 * UnLink the instance from our list
	 */
	if (ecvi->next) {
		ecvi->next->prev = ecvi->prev;
	}
	if (ecvi->prev) {
		ecvi->prev->next = ecvi->next;
	} else {
		DEBUG_ASSERT(ecm_classifier_ovs_instances == ecvi, "%px: list bad %px\n", ecvi, ecm_classifier_ovs_instances);
		ecm_classifier_ovs_instances = ecvi->next;
	}
	spin_unlock_bh(&ecm_classifier_ovs_lock);

	/*
	 * Final
	 */
	DEBUG_INFO("%px: Final ovs classifier instance\n", ecvi);
	kfree(ecvi);

	return 0;
}

/*
 * ecm_classifier_ovs_interface_get_and_ref()
 *	Gets the OVS bridge port in the specified direction hierarchy.
 */
static inline struct net_device *ecm_classifier_ovs_interface_get_and_ref(struct ecm_db_connection_instance *ci,
									   ecm_db_obj_dir_t dir, bool ovs_port)
{
	int32_t if_first;
	struct ecm_db_iface_instance *interfaces[ECM_DB_IFACE_HEIRARCHY_MAX];
	int32_t i;

	/*
	 * Get the interface hierarchy.
	 */
	if_first = ecm_db_connection_interfaces_get_and_ref(ci, interfaces, dir);
	if (if_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
		DEBUG_WARN("%px: Failed to get %s interfaces list\n", ci, ecm_db_obj_dir_strings[dir]);
		return NULL;
	}

	/*
	 * Go through the hierarchy and get the OVS port.
	 */
	for (i = ECM_DB_IFACE_HEIRARCHY_MAX - 1; i >= if_first; i--) {
		struct net_device *dev = dev_get_by_index(&init_net,
							  ecm_db_iface_interface_identifier_get(interfaces[i]));
		if (!dev) {
			DEBUG_WARN("%px: Failed to get net device with %d index\n", ci, i);
			continue;
		}

		if (ovs_port) {
			if (ecm_interface_is_ovs_bridge_port(dev)) {
				ecm_db_connection_interfaces_deref(interfaces, if_first);
				DEBUG_TRACE("%px: %s_dev: %s at %d index is an OVS bridge port\n", ci, ecm_db_obj_dir_strings[dir], dev->name, i);
				return dev;
			}

		} else {
			if (ovsmgr_is_ovs_master(dev)) {
				ecm_db_connection_interfaces_deref(interfaces, if_first);
				DEBUG_TRACE("%px: %s_dev: %s at %d index is an OVS bridge dev\n", ci, ecm_db_obj_dir_strings[dir], dev->name, i);
				return dev;
			}
		}

		DEBUG_TRACE("%px: dev: %s index: %d\n", ci, dev->name, i);
		dev_put(dev);
	}

	DEBUG_TRACE("%px: No OVS bridge port on the %s direction\n", ci, ecm_db_obj_dir_strings[dir]);
	ecm_db_connection_interfaces_deref(interfaces, if_first);
	return NULL;
}

#ifdef ECM_MULTICAST_ENABLE
/*
 * ecm_classifier_ovs_process_multicast()
 * 	Process multicast packet
 */
static void ecm_classifier_ovs_process_multicast(struct ecm_db_connection_instance *ci, struct sk_buff *skb,
							struct ecm_classifier_ovs_instance *ecvi,
							struct ecm_classifier_process_response *process_response)
{
	struct ecm_classifier_ovs_process_response resp;
	ecm_classifier_ovs_process_callback_t cb;
	struct ecm_db_iface_instance *to_mc_ifaces;
	struct net_device *from_dev = NULL, *indev_master = NULL;
	struct net_device *to_dev[ECM_DB_MULTICAST_IF_MAX] = {NULL};
	struct ovsmgr_dp_flow flow;
	ip_addr_t src_ip;
	ip_addr_t dst_ip;
	int32_t *to_mc_ifaces_first;
	int if_cnt, i;
	bool valid_ovs_ports = false;

	/*
	 * Classifier is always relevant for multicast
	 * if we have enabled OVS support in ECM.
	 */
	spin_lock_bh(&ecm_classifier_ovs_lock);
	ecvi->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
	spin_unlock_bh(&ecm_classifier_ovs_lock);

	/*
	 * No multicast port found, drop the connection.
	 */
	if_cnt = ecm_db_multicast_connection_to_interfaces_get_and_ref_all(ci, &to_mc_ifaces, &to_mc_ifaces_first);
	if (unlikely(!if_cnt)) {
		spin_lock_bh(&ecm_classifier_ovs_lock);
		ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_DROP;
		ecvi->process_response.drop = true;
		*process_response = ecvi->process_response;
		spin_unlock_bh(&ecm_classifier_ovs_lock);
		DEBUG_WARN("%px: No multicast 'to' interface found\n", ci);
		goto done;
	}

	for (i = 0; i < ECM_DB_MULTICAST_IF_MAX; i++) {
		int32_t *to_iface_first;
		int j;

		/*
		 * Get to interface list, skip if the list is invalid.
		 */
		to_iface_first = ecm_db_multicast_if_first_get_at_index(to_mc_ifaces_first, i);
		if (*to_iface_first == ECM_DB_IFACE_HEIRARCHY_MAX) {
			continue;
		}

		for (j = to_mc_ifaces_first[i]; j < ECM_DB_IFACE_HEIRARCHY_MAX; j++) {
			struct ecm_db_iface_instance **ifaces;
			struct ecm_db_iface_instance *ii_temp;
			struct net_device *to_dev_temp;

			ii_temp = ecm_db_multicast_if_heirarchy_get(to_mc_ifaces, i);
			ifaces = (struct ecm_db_iface_instance **)ecm_db_multicast_if_instance_get_at_index(ii_temp, j);
			to_dev_temp = dev_get_by_index(&init_net, ecm_db_iface_interface_identifier_get(*ifaces));
			if (unlikely(!to_dev_temp)) {
				continue;
			}

			/*
			 * Get the physical OVS port.
			 */
			if (!ecm_interface_is_ovs_bridge_port(to_dev_temp)) {
				dev_put(to_dev_temp);
				continue;
			}

			to_dev[i] = to_dev_temp;
			valid_ovs_ports = true;
		}
	}
	ecm_db_multicast_connection_to_interfaces_deref_all(to_mc_ifaces, to_mc_ifaces_first);

	from_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_FROM, true);
	if (!from_dev && !valid_ovs_ports) {
		spin_lock_bh(&ecm_classifier_ovs_lock);
		*process_response = ecvi->process_response;
		spin_unlock_bh(&ecm_classifier_ovs_lock);
		DEBUG_WARN("%px: None of the from/to interfaces are OVS bridge port\n", ci);
		goto done;
	}

	/*
	 * Below are the possible multicast flows.
	 *
	 * 1. L2 Multicast (Bridge)
	 * 	ovsbr (eth0, eth1,eth2)
	 * 	a. sender: eth0, receiver: eth1, eth2
	 *
	 * 2. L3 Multicast (Route)
	 * 	Upstream: br-wan (eth0)
	 * 	Downstream: br-home (eth1, eth2)
	 * 	a. Downstream flow => sender: eth0, receiver: eth1, eth2
	 * 	b. Upstream flow => sender: eth1, receiver: eth0
	 *
	 * 3. L2 + L3 Multicast (Bridge + Route)
	 * 	Upstream: br-wan (eth0)
	 * 	Downstream: br-home (eth1, eth2)
	 * 	a. sender: eth1, receiver: eth0, eth2
	 */

	/*
	 * Is there an external callback to get the ovs value from the packet?
	 */
	spin_lock_bh(&ecm_classifier_ovs_lock);
	cb = ovs.ovs_process;
	if (!cb) {
		/*
		 * Allow acceleration.
		 * Keep the classifier relevant to connection for stats update..
		 */
		spin_unlock_bh(&ecm_classifier_ovs_lock);
		DEBUG_WARN("%px: No external process callback set\n", ci);
		goto allow_accel;
	}
	spin_unlock_bh(&ecm_classifier_ovs_lock);

	memset(&flow, 0, sizeof(struct ovsmgr_dp_flow));

	if (from_dev) {
		flow.indev = from_dev;
		indev_master = ovsmgr_dev_get_master(flow.indev);
		DEBUG_ASSERT(indev_master, "%px: Expected a master\n", ci);
	}

	flow.is_routed = ecm_db_connection_is_routed_get(ci);
	flow.tuple.ip_version = ecm_db_connection_ip_version_get(ci);
	flow.tuple.protocol = ecm_db_connection_protocol_get(ci);
	flow.tuple.src_port = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM));
	flow.tuple.dst_port = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO));

	ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, flow.smac);
	ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_TO, flow.dmac);
	ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM, src_ip);
	ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dst_ip);

	if (flow.tuple.ip_version == 4) {
		ECM_IP_ADDR_TO_NIN4_ADDR(flow.tuple.ipv4.src, src_ip);
		ECM_IP_ADDR_TO_NIN4_ADDR(flow.tuple.ipv4.dst, dst_ip);
	} else if (flow.tuple.ip_version == 6) {
		ECM_IP_ADDR_TO_NIN6_ADDR(flow.tuple.ipv6.src, src_ip);
		ECM_IP_ADDR_TO_NIN6_ADDR(flow.tuple.ipv6.dst, dst_ip);
	} else {
		DEBUG_ASSERT(NULL, "%px: unexpected ip_version: %d", ci, flow.tuple.ip_version );
	}

	/*
	 * Check if the connection is a "bridge + route"
	 * flow.
	 */
	if (flow.is_routed) {
		/*
		 * Get the ingress VLAN information from ovs-mgr
		 */
		if (from_dev) {
			struct net_device *br_dev;
			ecm_classifier_ovs_result_t result;

			/*
			 * from_dev = eth1
			 * br_dev = ovs-br1
			 */
			br_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_FROM, false);
			DEBUG_TRACE("%px: processing route flow from_dev = %s, br_dev = %s", ecvi, from_dev->name, br_dev->name);

			/*
			 * We always take the flow from bridge to port, so indev is port device and outdev is bridge device.
			 */
			flow.indev = from_dev;
			flow.outdev = br_dev;

			DEBUG_TRACE("%px: Route Flow Process (from): src MAC: %pM src_dev: %s src: %pI4:%d proto: %d dest: %pI4:%d dest_dev: %s dest MAC: %pM\n",
					&flow, flow.smac, flow.indev->name, &flow.tuple.ipv4.src, flow.tuple.src_port, flow.tuple.protocol,
					&flow.tuple.ipv4.dst, flow.tuple.dst_port, flow.outdev->name, flow.dmac);

			memset(&resp, 0, sizeof(struct ecm_classifier_ovs_process_response));

			/*
			 * Call the external callback and get the result.
			 */
			result = cb(&flow, skb, &resp);

			dev_put(br_dev);

			/*
			 * Handle the result
			 */
			switch (result) {
			case ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_ACCEL:
			case ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_QINQ_ACCEL:
				/*
				 * Allow accel after setting the external module response.
				 */
				DEBUG_WARN("%px: External callback process succeeded\n", ecvi);
				spin_lock_bh(&ecm_classifier_ovs_lock);
				ecvi->process_response.ingress_vlan_tag[0] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
				ecvi->process_response.ingress_vlan_tag[1] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
				if (resp.egress_vlan[0].h_vlan_TCI) {
					ecvi->process_response.ingress_vlan_tag[0] = resp.egress_vlan[0].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[0].h_vlan_TCI;
				}

				ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_TAG;
				if (result == ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_QINQ_ACCEL) {
					if (resp.egress_vlan[1].h_vlan_TCI) {
						ecvi->process_response.ingress_vlan_tag[1] = resp.egress_vlan[1].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[1].h_vlan_TCI;
					}

					ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_QINQ_TAG;
				}
				spin_unlock_bh(&ecm_classifier_ovs_lock);
				DEBUG_TRACE("%px: Multicast ingress vlan tag[0]: %x tag[1]: %x\n", ecvi, ecvi->process_response.ingress_vlan_tag[0],
						ecvi->process_response.ingress_vlan_tag[1]);
				break;

			case ECM_CLASSIFIER_OVS_RESULT_DENY_ACCEL:
				/*
				 * External callback failed to process VLAN process. So, let's deny the acceleration
				 * and try more with the subsequent packets.
				 */
				DEBUG_WARN("%px: External callback failed to process VLAN tags\n", ecvi);
				spin_lock_bh(&ecm_classifier_ovs_lock);
				ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_MCAST_DENY_ACCEL;
				ecvi->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
				*process_response = ecvi->process_response;
				spin_unlock_bh(&ecm_classifier_ovs_lock);
				goto done;

			case ECM_CLASSIFIER_OVS_RESULT_ALLOW_ACCEL:
				/*
				 * There is no VLAN tag in the flow. Just allow the acceleration.
				 */
				DEBUG_WARN("%px: External callback didn't find any VLAN relation\n", ecvi);
				break;

			default:
				DEBUG_ASSERT(false, "%px: Unhandled result: %d\n", ci, result);
			}
		}
	}

	/*
	 * During multicast update path, skb is passed as NULL.
	 * We need to fill the ingress_vlan with the same vlan
	 * information that we have stored during connection instance
	 * creation. OVS manager needs this information to provide the
	 * right response.
	 */
	if (!skb) {
		flow.ingress_vlan = ecm_db_multicast_tuple_get_ovs_ingress_vlan(ci->ti);
	}

	/*
	 * Call the external callback and get the result.
	 */
	for (i = 0; i < ECM_DB_MULTICAST_IF_MAX; i++) {
		ecm_classifier_ovs_result_t result = 0;

		if (!to_dev[i]) {
			continue;
		}

		flow.outdev = to_dev[i];

		/*
		 * For routed flows, indev should be the OVS bridge of the
		 * corresponding port.
		 */
		if (flow.is_routed) {
			struct net_device *outdev_master;

			/*
			 * During bridge+route scenario, the indev can be
			 * an ovs bridge port or and ovs bridge. if master device
			 * for indev and outdev are same then it a bridged traffic.
			 * Otherwise, set the indev to master of the egress port.
			 */
			outdev_master = ovsmgr_dev_get_master(flow.outdev);
			DEBUG_ASSERT(outdev_master, "%px: Expected a master\n", ci);
			if (indev_master && (indev_master->ifindex == outdev_master->ifindex)) {
				flow.indev = from_dev;
				ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, flow.smac);
			} else {
				flow.indev = outdev_master;
				ether_addr_copy(flow.smac, flow.indev->dev_addr);
			}
		}

		DEBUG_TRACE("%px: src MAC: %pM src_dev: %s src: %pI4:%d proto: %d dest: %pI4:%d dest_dev: %s dest MAC: %pM\n",
				ci, flow.smac, flow.indev->name, &flow.tuple.ipv4.src, flow.tuple.src_port, flow.tuple.protocol,
				&flow.tuple.ipv4.dst, flow.tuple.dst_port, flow.outdev->name, flow.dmac);

		memset(&resp, 0, sizeof(struct ecm_classifier_ovs_process_response));
		result = cb(&flow, skb, &resp);

		switch(result) {
		case ECM_CLASSIFIER_OVS_RESULT_DENY_ACCEL_EGRESS:
			DEBUG_TRACE("%px: %s is not a valid OVS port\n", ci, to_dev[i]->name);
			ecm_db_multicast_connection_to_interfaces_clear_at_index(ci, i);
			break;

		case ECM_CLASSIFIER_OVS_RESULT_DENY_ACCEL:
			/*
			 * If we receive "ECM_CLASSIFIER_OVS_RESULT_DENY_ACCEL"
			 * for any of the OVS port, then the connection should be
			 * deleted.
			 */
			DEBUG_TRACE("%px: flow does not exist for the OVS port: %s\n", ci, to_dev[i]->name);
			spin_lock_bh(&ecm_classifier_ovs_lock);
			ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_MCAST_DENY_ACCEL;
			ecvi->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
			*process_response = ecvi->process_response;
			spin_unlock_bh(&ecm_classifier_ovs_lock);
			goto done;

		case ECM_CLASSIFIER_OVS_RESULT_ALLOW_ACCEL:
			DEBUG_TRACE("%px: Acceleration allowed for multicast OVS port: %s\n", ci, to_dev[i]->name);
			break;

		case ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_ACCEL:
		case ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_QINQ_ACCEL:
			/*
			 * Allow accel after setting the external module response.
			 * Primary VLAN tag is always present even it is QinQ.
			 */
			DEBUG_WARN("%px: External callback process succeeded\n", ci);

			/*
			 * Initialize the VLAN entries since the ports can join/leave
			 * in-between and that will change the position of an existing port
			 * in the "egress_mc_vlan_tag" array.
			 */
			spin_lock_bh(&ecm_classifier_ovs_lock);
			ecvi->process_response.egress_mc_vlan_tag[i][0] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
			ecvi->process_response.egress_mc_vlan_tag[i][1] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
			ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_TAG;
			ecvi->process_response.egress_netdev_index[i] = flow.outdev->ifindex;

			/*
			 * If we have a valid TCI for ingress VLAN then we assume
			 * the flow is bridged. Because for routed flows, ingress VLAN
			 * will not be available.
			 */
			if (resp.ingress_vlan[0].h_vlan_TCI) {
				ecvi->process_response.ingress_vlan_tag[0] = resp.ingress_vlan[0].h_vlan_encapsulated_proto << 16 | resp.ingress_vlan[0].h_vlan_TCI;
			}

			if (resp.egress_vlan[0].h_vlan_TCI) {
				ecvi->process_response.egress_mc_vlan_tag[i][0] = resp.egress_vlan[0].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[0].h_vlan_TCI;
			}

			if (result == ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_QINQ_ACCEL) {
				if (resp.ingress_vlan[1].h_vlan_TCI) {
					ecvi->process_response.ingress_vlan_tag[1] = resp.ingress_vlan[1].h_vlan_encapsulated_proto << 16 | resp.ingress_vlan[1].h_vlan_TCI;
				}

				if (resp.egress_vlan[1].h_vlan_TCI) {
					ecvi->process_response.egress_mc_vlan_tag[i][1] = resp.egress_vlan[1].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[1].h_vlan_TCI;
				}

				ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_QINQ_TAG;
			}

			spin_unlock_bh(&ecm_classifier_ovs_lock);
			DEBUG_TRACE("%px: Multicast ingress vlan tag[0] : 0x%x tag[1] : 0x%x\n", ci, ecvi->process_response.ingress_vlan_tag[0],
					ecvi->process_response.ingress_vlan_tag[1]);
			DEBUG_TRACE("%px: Multicast egress vlan tag[%d][0] : 0x%x tag[%d][1] : 0x%x\n", ci, i, ecvi->process_response.egress_mc_vlan_tag[i][0],
					i, ecvi->process_response.egress_mc_vlan_tag[i][1]);
			break;

		default:
			DEBUG_ASSERT(false, "Unhandled result: %d\n", result);
		}
	}

	/*
	 * It is possible that after verifying each egress port with ovs manager,
	 * no egress ovs ports are allowed for acceleration.
	 *
	 * Deny the multicast connection as there are no active 'to' interface.
	 */
	if (!ecm_db_multicast_connection_to_interfaces_get_count(ci)) {
		DEBUG_TRACE("%px: No valid multicast 'to' interfaces found\n", ci);
		spin_lock_bh(&ecm_classifier_ovs_lock);
		ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_MCAST_DENY_ACCEL;
		ecvi->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
		*process_response = ecvi->process_response;
		spin_unlock_bh(&ecm_classifier_ovs_lock);
		goto done;
	}

allow_accel:
	spin_lock_bh(&ecm_classifier_ovs_lock);
	ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
	ecvi->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_ACCEL;
	*process_response = ecvi->process_response;
	spin_unlock_bh(&ecm_classifier_ovs_lock);

done:
	if (from_dev)
		dev_put(from_dev);

	/*
	 * Deref the ovs net devices
	 */
	if (valid_ovs_ports) {
		for (i = 0; i < ECM_DB_MULTICAST_IF_MAX; i++) {
			if (to_dev[i]) {
				dev_put(to_dev[i]);
			}
		}
	}

	return;
}
#endif

/*
 * ecm_classifier_ovs_process_route_flow()
 *	Process routed flows.
 */
static void ecm_classifier_ovs_process_route_flow(struct ecm_classifier_ovs_instance *ecvi, struct ecm_db_connection_instance *ci,
							struct sk_buff *skb, struct net_device *from_dev, struct net_device *to_dev,
							struct ecm_classifier_process_response *process_response,
							ecm_classifier_ovs_process_callback_t cb)
{
	ecm_classifier_ovs_result_t result;
	struct ecm_classifier_ovs_process_response resp;
	struct ovsmgr_dp_flow flow;
	struct net_device *br_dev;
	ip_addr_t src_ip, dst_ip;

	memset(&flow, 0, sizeof(flow));

	flow.is_routed = true;
	flow.tuple.ip_version = ecm_db_connection_ip_version_get(ci);
	flow.tuple.protocol = ecm_db_connection_protocol_get(ci);

	/*
	 * For routed flows both from and to side can be OVS bridge port, if there
	 * is a routed flow between two OVS bridges. (e.g: ovs-br1 and ovs-br2)
	 *
	 * Connection Direction:
	 * 				PC1 -----> eth1-ovs-br1 (DUT) ovs-br2-eth2 -----> PC2
							from_dev	to_dev
	 *
	 * 1. SNAT/DNAT Enabled:	FROM				FROM_NAT	TO/TO_NAT
	 * 2. SNAT/DNAT Disabled:	FROM/FROM_NAT					TO/TO_NAT
	 *
	 * Connection Direction:
	 * 				PC1 <----- eth1-ovs-br1 (DUT) ovs-br2-eth2 <----- PC2
	 *						to_dev		from_dev
	 *
	 * 3. SNAT/DNAT Enabled:	TO				TO_NAT		FROM/FROM_NAT
	 * 4. SNAT/DNAT Disabled:	TO/TO_NAT					FROM/FROM_NAT
	 *
	 * 5. Tunnelled packet:  PC1 ------------> eth1---[ovs-br1]---gretap (DUT) eth0----->[gretap device]
	 * 	After the packet is encapsulated, the packet is routed and the
	 * 	flow is not relavant flow.
	 */
	if (from_dev) {
		/*
		 * Case 1/2
		 * from_dev = eth1
		 * br_dev = ovs-br1
		 *
		 * Case 3/4
		 * from_dev = eth2
		 * br_dev = ovs-br2
		 *
		 * case 5
		 * from_dev = greptap
		 * br_dev = NULL
		 */
		br_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_FROM, false);
		if (!br_dev) {
			DEBUG_WARN("%px: from_dev = %s is a OVS bridge port, bridge interface is not found\n",
					ecvi, from_dev->name);
			goto route_not_relevant;
		}

		DEBUG_TRACE("%px: processing route flow from_dev = %s, br_dev = %s", ecvi, from_dev->name, br_dev->name);

		/*
		 * We always take the flow from bridge to port, so indev is brdige and outdev is port device.
		 */
		flow.indev = br_dev;
		flow.outdev = from_dev;

		flow.tuple.src_port = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO_NAT));
		flow.tuple.dst_port = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM));

		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO_NAT, src_ip);
		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM, dst_ip);

		if (flow.tuple.ip_version == 4) {
			ECM_IP_ADDR_TO_NIN4_ADDR(flow.tuple.ipv4.src, src_ip);
			ECM_IP_ADDR_TO_NIN4_ADDR(flow.tuple.ipv4.dst, dst_ip);
		} else if (flow.tuple.ip_version == 6) {
			ECM_IP_ADDR_TO_NIN6_ADDR(flow.tuple.ipv6.src, src_ip);
			ECM_IP_ADDR_TO_NIN6_ADDR(flow.tuple.ipv6.dst, dst_ip);
		} else {
			DEBUG_ASSERT(NULL, "%px: unexpected ip_version: %d", ecvi, flow.tuple.ip_version );
		}

		ether_addr_copy(flow.smac, br_dev->dev_addr);
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, flow.dmac);

		memset(&resp, 0, sizeof(struct ecm_classifier_ovs_process_response));

		/*
		 * Initialize the dscp with the default value.
		 */
		resp.dscp = OVSMGR_INVALID_DSCP;

		DEBUG_TRACE("%px: Route Flow Process (from): src MAC: %pM src_dev: %s src: %pI4:%d proto: %d dest: %pI4:%d dest_dev: %s dest MAC: %pM\n",
				&flow, flow.smac, flow.indev->name, &flow.tuple.ipv4.src, flow.tuple.src_port, flow.tuple.protocol,
				&flow.tuple.ipv4.dst, flow.tuple.dst_port, flow.outdev->name, flow.dmac);
		/*
		 * Call the external callback and get the result.
		 */
		result = cb(&flow, skb, &resp);

		dev_put(br_dev);

		if (resp.dscp != OVSMGR_INVALID_DSCP) {
			/*
			 * Copy DSCP value to the classifier's process response's flow_dscp field,
			 * because this is the from_dev and the direction of the flow is flow direction.
			 */
			spin_lock_bh(&ecm_classifier_ovs_lock);
			ecvi->process_response.flow_dscp = resp.dscp >> XT_DSCP_SHIFT;
			ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_DSCP;
			spin_unlock_bh(&ecm_classifier_ovs_lock);
			DEBUG_TRACE("FLOW DSCP : 0x%x\n", ecvi->process_response.flow_dscp);
		}

		/*
		 * Handle the result
		 */
		switch (result) {
		case ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_ACCEL:
		case ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_QINQ_ACCEL:
			/*
			 * Allow accel after setting the external module response.
			 */
			DEBUG_WARN("%px: External callback process succeeded\n", ecvi);

			spin_lock_bh(&ecm_classifier_ovs_lock);
			if (resp.egress_vlan[0].h_vlan_TCI) {
				ecvi->process_response.ingress_vlan_tag[0] = resp.egress_vlan[0].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[0].h_vlan_TCI;
				DEBUG_TRACE("Ingress vlan tag[0] set : %x\n", ecvi->process_response.ingress_vlan_tag[0]);
			}

			ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_TAG;

			if (result == ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_QINQ_ACCEL) {
				if (resp.egress_vlan[1].h_vlan_TCI) {
					ecvi->process_response.ingress_vlan_tag[1] = resp.egress_vlan[1].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[1].h_vlan_TCI;
					DEBUG_TRACE("Ingress vlan tag[0] set : %x\n", ecvi->process_response.ingress_vlan_tag[1]);
				}

				ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_QINQ_TAG;
			}
			spin_unlock_bh(&ecm_classifier_ovs_lock);
			break;

		case ECM_CLASSIFIER_OVS_RESULT_DENY_ACCEL:
			/*
			 * External callback failed to process VLAN process. So, let's deny the acceleration
			 * and try more with the subsequent packets.
			 */
			DEBUG_WARN("%px: External callback failed to process VLAN tags\n", ecvi);
			goto route_deny_accel;

		case ECM_CLASSIFIER_OVS_RESULT_ALLOW_ACCEL:

			/*
			 * There is no VLAN tag in the flow. Just allow the acceleration.
			 */
			DEBUG_WARN("%px: External callback didn't find any VLAN relation\n", ecvi);
			break;

		default:
			DEBUG_ASSERT(false, "Unhandled result: %d\n", result);
		}
	}

	if (to_dev) {
		/*
		 * Case 1/2
		 * from_dev = eth2
		 * br_dev = ovs-br2
		 *
		 * Case 3/4
		 * from_dev = eth1
		 * br_dev = ovs-br1
		 */
		br_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_TO, false);
		if (!br_dev) {
			DEBUG_WARN("%px: to_dev = %s is a OVS bridge port, bridge interface is not found\n",
					ecvi, to_dev->name);
			goto route_deny_accel;
		}

		DEBUG_TRACE("%px: processing route flow to_dev = %s, br_dev = %s", ecvi, to_dev->name, br_dev->name);

		flow.indev = br_dev;
		flow.outdev = to_dev;

		flow.tuple.src_port = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM_NAT));
		flow.tuple.dst_port = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO));

		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM_NAT, src_ip);
		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dst_ip);

		if (flow.tuple.ip_version == 4) {
			ECM_IP_ADDR_TO_NIN4_ADDR(flow.tuple.ipv4.src, src_ip);
			ECM_IP_ADDR_TO_NIN4_ADDR(flow.tuple.ipv4.dst, dst_ip);
		} else if (flow.tuple.ip_version == 6) {
			ECM_IP_ADDR_TO_NIN6_ADDR(flow.tuple.ipv6.src, src_ip);
			ECM_IP_ADDR_TO_NIN6_ADDR(flow.tuple.ipv6.dst, dst_ip);
		} else {
			DEBUG_ASSERT(NULL, "%px: unexpected ip_version: %d", ecvi, flow.tuple.ip_version );
		}

		ether_addr_copy(flow.smac, br_dev->dev_addr);
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_TO, flow.dmac);

		memset(&resp, 0, sizeof(struct ecm_classifier_ovs_process_response));

		/*
		 * Initialize the dscp with the default value.
		 */
		resp.dscp = OVSMGR_INVALID_DSCP;

		DEBUG_TRACE("%px: Route Flow Process (to): src MAC: %pM src_dev: %s src: %pI4:%d proto: %d dest: %pI4:%d dest_dev: %s dest MAC: %pM\n",
				&flow, flow.smac, flow.indev->name, &flow.tuple.ipv4.src, flow.tuple.src_port, flow.tuple.protocol,
				&flow.tuple.ipv4.dst, flow.tuple.dst_port, flow.outdev->name, flow.dmac);
		/*
		 * Call the external callback and get the result.
		 */
		result = cb(&flow, skb, &resp);

		dev_put(br_dev);

		if (resp.dscp != OVSMGR_INVALID_DSCP) {
			/*
			 * Copy DSCP value to the classifier's process response's return_dscp field,
			 * because this is the to_dev and the direction of the flow is reply direction.
			 */
			spin_lock_bh(&ecm_classifier_ovs_lock);
			ecvi->process_response.return_dscp = resp.dscp >> XT_DSCP_SHIFT;
			ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_DSCP;
			spin_unlock_bh(&ecm_classifier_ovs_lock);
			DEBUG_TRACE("RETURN DSCP : 0x%x\n", ecvi->process_response.return_dscp);
		}

		/*
		 * Handle the result
		 */
		switch (result) {
		case ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_ACCEL:
		case ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_QINQ_ACCEL:
			/*
			 * Allow accel after setting the external module response.
			 */
			DEBUG_WARN("%px: External callback process succeeded\n", ecvi);

			spin_lock_bh(&ecm_classifier_ovs_lock);
			if (resp.egress_vlan[0].h_vlan_TCI) {
				ecvi->process_response.egress_vlan_tag[0] = resp.egress_vlan[0].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[0].h_vlan_TCI;
				DEBUG_TRACE("Egress vlan tag[0] set : %x\n", ecvi->process_response.egress_vlan_tag[0]);
			}

			ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_TAG;

			if (result == ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_QINQ_ACCEL) {
				if (resp.egress_vlan[1].h_vlan_TCI) {
					ecvi->process_response.egress_vlan_tag[1] = resp.egress_vlan[1].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[1].h_vlan_TCI;
					DEBUG_TRACE("Ingress vlan tag[0] set : %x\n", ecvi->process_response.ingress_vlan_tag[1]);
				}

				ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_QINQ_TAG;
			}
			spin_unlock_bh(&ecm_classifier_ovs_lock);
			break;

		case ECM_CLASSIFIER_OVS_RESULT_DENY_ACCEL:
			/*
			 * External callback failed to process VLAN process. So, let's deny the acceleration
			 * and try more with the subsequent packets.
			 */
			DEBUG_WARN("%px: External callback failed to process VLAN tags\n", ecvi);
			goto route_deny_accel;

		case ECM_CLASSIFIER_OVS_RESULT_ALLOW_ACCEL:

			/*
			 * There is no VLAN tag in the flow. Just allow the acceleration.
			 */
			DEBUG_WARN("%px: External callback didn't find any VLAN relation\n", ecvi);
			break;

		default:
			DEBUG_ASSERT(false, "Unhandled result: %d\n", result);
		}
	}

	/*
	 * Acceleration is permitted
	 */
	spin_lock_bh(&ecm_classifier_ovs_lock);
	ecvi->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
	ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
	ecvi->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_ACCEL;
	*process_response = ecvi->process_response;
	spin_unlock_bh(&ecm_classifier_ovs_lock);

	return;

route_deny_accel:
	/*
	 * ecm_classifier_ovs_lock MUST be held
	 */
	spin_lock_bh(&ecm_classifier_ovs_lock);
	ecvi->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
	ecvi->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
	ecvi->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
	*process_response = ecvi->process_response;
	spin_unlock_bh(&ecm_classifier_ovs_lock);

	return;

route_not_relevant:
	/*
	 * ecm_classifier_ovs_lock MUST be held
	 */
	spin_lock_bh(&ecm_classifier_ovs_lock);
	ecvi->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_NO;
	*process_response = ecvi->process_response;
	spin_unlock_bh(&ecm_classifier_ovs_lock);
}

/*
 * ecm_classifier_ovs_process()
 *	Process new packet
 *
 * NOTE: This function would only ever be called if all other classifiers have failed.
 */
static void ecm_classifier_ovs_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_classifier_ovs_instance *ecvi = (struct ecm_classifier_ovs_instance *)aci;
	ecm_classifier_ovs_result_t result = 0;
	struct ecm_db_connection_instance *ci;
	ecm_classifier_ovs_process_callback_t cb = NULL;
	ip_addr_t src_ip;
	ip_addr_t dst_ip;
	struct ecm_classifier_ovs_process_response resp;
	struct ovsmgr_dp_flow flow;
	struct net_device *from_dev = NULL;
	struct net_device *to_dev = NULL;

	DEBUG_CHECK_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC, "%px: invalid state magic\n", ecvi);

	/*
	 * Not relevant to the connection if not enabled.
	 */
	if (unlikely(!ecm_classifier_ovs_enabled)) {
		/*
		 * Not relevant.
		 */
		DEBUG_WARN("%px: ovs classifier is not enabled\n", aci);
		goto not_relevant;
	}

	/*
	 * Get connection
	 */
	ci = ecm_db_connection_serial_find_and_ref(ecvi->ci_serial);
	if (!ci) {
		/*
		 * Connection has gone from under us
		 */
		DEBUG_WARN("%px: connection instance gone while processing classifier\n", aci);
		goto not_relevant;
	}

#ifdef ECM_MULTICAST_ENABLE
	ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dst_ip);
	if (ecm_ip_addr_is_multicast(dst_ip)) {
		ecm_classifier_ovs_process_multicast(ci, skb, ecvi, process_response);
		ecm_db_connection_deref(ci);
		return;
	}
#endif

	/*
	 * Get the possible OVS bridge ports. If both are NULL, the classifier is not
	 * relevant to this connection.
	 */
	from_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_FROM, true);
	to_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_TO, true);
	if (!from_dev && !to_dev) {
		/*
		 * So, the classifier is not relevant to this connection.
		 */
		DEBUG_WARN("%px: None of the from/to interfaces are OVS bridge port\n", aci);
		ecm_db_connection_deref(ci);
		goto not_relevant;
	}

	/*
	 * Is there an external callback to get the ovs value from the packet?
	 */
	spin_lock_bh(&ecm_classifier_ovs_lock);
	cb = ovs.ovs_process;
	if (!cb) {
		/*
		 * Allow acceleration.
		 * Keep the classifier relevant to connection for stats update..
		 */
		spin_unlock_bh(&ecm_classifier_ovs_lock);
		DEBUG_WARN("%px: No external process callback set\n", aci);
		if (from_dev)
			dev_put(from_dev);

		if (to_dev)
			dev_put(to_dev);

		spin_lock_bh(&ecm_classifier_ovs_lock);
		goto allow_accel;
	}
	spin_unlock_bh(&ecm_classifier_ovs_lock);

	/*
	 * If the flow is a routed flow, set the is_routed flag of the flow.
	 */
	if (ecm_db_connection_is_routed_get(ci)) {
		ecm_classifier_ovs_process_route_flow(ecvi, ci, skb, from_dev, to_dev, process_response, cb);

		if (from_dev)
			dev_put(from_dev);

		if (to_dev)
			dev_put(to_dev);

		ecm_db_connection_deref(ci);
		return;
	}

	memset(&flow, 0, sizeof(struct ovsmgr_dp_flow));

	/*
	 * If the connection is a bridge flow, both devices should be present.
	 * TODO: This is an unexpected situation and should be assertion.
	 * We should also make sure that both devices are on the same OVS bridge.
	 */
	if (!from_dev || !to_dev) {
		DEBUG_ERROR("%px: One of the ports is NULL from_dev: %px to_dev: %px\n", aci, from_dev, to_dev);

		if (from_dev)
			dev_put(from_dev);

		if (to_dev)
			dev_put(to_dev);

		ecm_db_connection_deref(ci);
		goto not_relevant;
	}

	/*
	 * Flow is an OVS bridge flow.
	 */
	flow.tuple.ip_version = ecm_db_connection_ip_version_get(ci);
	flow.tuple.protocol = ecm_db_connection_protocol_get(ci);

	/*
	 * For the flow lookup, we need to use the  proper 5-tuple, in/out dev and
	 * src/dest MAC address. If the packet is coming from the destination side of the connection
	 * (e.g: ACK packets of the TCP connection) these values should be reversed.
	 */
	if (sender == ECM_TRACKER_SENDER_TYPE_SRC) {
		DEBUG_TRACE("%px: sender is SRC\n", aci);
		flow.indev = from_dev;
		flow.outdev = to_dev;

		flow.tuple.src_port = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM));
		flow.tuple.dst_port = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO));

		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM, src_ip);
		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dst_ip);
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, flow.smac);
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_TO, flow.dmac);
	} else {
		DEBUG_TRACE("%px: sender is DEST\n", aci);
		flow.indev = to_dev;
		flow.outdev = from_dev;

		flow.tuple.src_port = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO));
		flow.tuple.dst_port = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM));

		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, src_ip);
		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM, dst_ip);
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_TO, flow.smac);
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, flow.dmac);

	}

	if (flow.tuple.ip_version == 4) {
		ECM_IP_ADDR_TO_NIN4_ADDR(flow.tuple.ipv4.src, src_ip);
		ECM_IP_ADDR_TO_NIN4_ADDR(flow.tuple.ipv4.dst, dst_ip);
	} else if (flow.tuple.ip_version == 6) {
		ECM_IP_ADDR_TO_NIN6_ADDR(flow.tuple.ipv6.src, src_ip);
		ECM_IP_ADDR_TO_NIN6_ADDR(flow.tuple.ipv6.dst, dst_ip);
	} else {
		DEBUG_ASSERT(NULL, "%px: unexpected ip_version: %d", aci, flow.tuple.ip_version );
	}

	memset(&resp, 0, sizeof(struct ecm_classifier_ovs_process_response));

	/*
	 * Set default values for flow and return DSCP.
	 * External module will call the DSCP query twice to
	 * find both directions' values.
	 */
	resp.flow_dscp = OVSMGR_INVALID_DSCP;
	resp.return_dscp = OVSMGR_INVALID_DSCP;

	/*
	 * Call the external callback and get the result.
	 */
	result = cb(&flow, skb, &resp);

	if (from_dev)
		dev_put(from_dev);

	if (to_dev)
		dev_put(to_dev);

	/*
	 * Handle the result
	 */
	switch (result) {
	case ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_ACCEL:
	case ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_QINQ_ACCEL:
		/*
		 * Allow accel after setting the external module response.
		 */
		DEBUG_WARN("%px: External callback process succeeded\n", aci);

		spin_lock_bh(&ecm_classifier_ovs_lock);
		ecvi->process_response.ingress_vlan_tag[0] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
		ecvi->process_response.egress_vlan_tag[0] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
		ecvi->process_response.ingress_vlan_tag[1] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
		ecvi->process_response.egress_vlan_tag[1] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;

		/*
		 * Primary VLAN tag is always present even it is QinQ.
		 */
		ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_TAG;

		/*
		 * If the sender type is source, which means the packet is coming from the originator,
		 * we assign the ECM-ingress<>OVS-ingress, ECM-egress<>OVS-egress values.
		 */
		if (sender == ECM_TRACKER_SENDER_TYPE_SRC) {
			if (resp.ingress_vlan[0].h_vlan_TCI) {
				ecvi->process_response.ingress_vlan_tag[0] = resp.ingress_vlan[0].h_vlan_encapsulated_proto << 16 | resp.ingress_vlan[0].h_vlan_TCI;
				DEBUG_TRACE("Ingress vlan tag[0] set : 0x%x\n", ecvi->process_response.ingress_vlan_tag[0]);
			}

			if (resp.egress_vlan[0].h_vlan_TCI) {
				ecvi->process_response.egress_vlan_tag[0] = resp.egress_vlan[0].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[0].h_vlan_TCI;
				DEBUG_TRACE("Egress vlan tag[0] set : 0x%x\n", ecvi->process_response.egress_vlan_tag[0]);
			}

			if (result == ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_QINQ_ACCEL) {
				if (resp.ingress_vlan[1].h_vlan_TCI) {
					ecvi->process_response.ingress_vlan_tag[1] = resp.ingress_vlan[1].h_vlan_encapsulated_proto << 16 | resp.ingress_vlan[1].h_vlan_TCI;
					DEBUG_TRACE("Ingress vlan tag[0] set : 0x%x\n", ecvi->process_response.ingress_vlan_tag[1]);
				}

				if (resp.egress_vlan[1].h_vlan_TCI) {
					ecvi->process_response.egress_vlan_tag[1] = resp.egress_vlan[1].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[1].h_vlan_TCI;
					DEBUG_TRACE("Egress vlan tag[1] set : 0x%x\n", ecvi->process_response.egress_vlan_tag[1]);
				}

				/*
				 * QinQ tag is present. Let's pass this information to the frontend through the process action flag.
				 */
				ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_QINQ_TAG;
			}
		} else {
			/*
			 * Sender type is destination, which means packet si coming from the counter originator side,
			 * we assign the ECM-ingress<>OVS-egress and ECM-egress<>OVS-ingress values.
			 */
			if (resp.ingress_vlan[0].h_vlan_TCI) {
				ecvi->process_response.egress_vlan_tag[0] = resp.ingress_vlan[0].h_vlan_encapsulated_proto << 16 | resp.ingress_vlan[0].h_vlan_TCI;
				DEBUG_TRACE("Egress vlan tag[0] set : 0x%x\n", ecvi->process_response.egress_vlan_tag[0]);
			}

			if (resp.egress_vlan[0].h_vlan_TCI) {
				ecvi->process_response.ingress_vlan_tag[0] = resp.egress_vlan[0].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[0].h_vlan_TCI;
				DEBUG_TRACE("Ingress vlan tag[0] set : 0x%x\n", ecvi->process_response.ingress_vlan_tag[0]);
			}

			if (result == ECM_CLASSIFIER_OVS_RESULT_ALLOW_VLAN_QINQ_ACCEL) {
				if (resp.ingress_vlan[1].h_vlan_TCI) {
					ecvi->process_response.egress_vlan_tag[1] = resp.ingress_vlan[1].h_vlan_encapsulated_proto << 16 | resp.ingress_vlan[1].h_vlan_TCI;
					DEBUG_TRACE("Egress vlan tag[0] set : 0x%x\n", ecvi->process_response.egress_vlan_tag[1]);
				}

				if (resp.egress_vlan[1].h_vlan_TCI) {
					ecvi->process_response.ingress_vlan_tag[1] = resp.egress_vlan[1].h_vlan_encapsulated_proto << 16 | resp.egress_vlan[1].h_vlan_TCI;
					DEBUG_TRACE("Ingress vlan tag[1] set : 0x%x\n", ecvi->process_response.ingress_vlan_tag[1]);
				}

				/*
				 * QinQ tag is present. Let's pass this information to the frontend through the process action flag.
				 */
				ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_QINQ_TAG;
			}
		}

		break;

	case ECM_CLASSIFIER_OVS_RESULT_DENY_ACCEL:
		/*
		 * External callback failed to process VLAN process. So, let's deny the acceleration
		 * and try more with the subsequent packets.
		 */
		DEBUG_WARN("%px: External callback failed to process VLAN tags\n", aci);
		goto deny_accel;

	case ECM_CLASSIFIER_OVS_RESULT_ALLOW_ACCEL:

		/*
		 * There is no VLAN tag in the flow. Just allow the acceleration.
		 */
		DEBUG_WARN("%px: External callback didn't find any VLAN relation\n", aci);
		spin_lock_bh(&ecm_classifier_ovs_lock);
		break;

	default:
		DEBUG_ASSERT(false, "Unhandled result: %d\n", result);
	}

	/*
	 * If external module set any of the flow or return DSCP,
	 * we copy them to the classifier's process response based
	 * on the direction of the traffic. The external module
	 * should always set first the flow and then the return values.
	 */
	if ((resp.flow_dscp != OVSMGR_INVALID_DSCP) || (resp.return_dscp != OVSMGR_INVALID_DSCP)) {
		if (sender == ECM_TRACKER_SENDER_TYPE_SRC) {
			/*
			 * Copy DSCP values
			 */
			ecvi->process_response.flow_dscp = (resp.flow_dscp != OVSMGR_INVALID_DSCP) ? resp.flow_dscp >> XT_DSCP_SHIFT : 0;
			ecvi->process_response.return_dscp = (resp.return_dscp != OVSMGR_INVALID_DSCP) ? resp.return_dscp >> XT_DSCP_SHIFT : ecvi->process_response.flow_dscp;
			DEBUG_TRACE("FLOW DSCP: 0x%x RETURN DSCP: 0x%x\n",
					ecvi->process_response.flow_dscp, ecvi->process_response.return_dscp);
		} else {
			/*
			 * Copy DSCP values
			 */
			ecvi->process_response.flow_dscp = (resp.return_dscp != OVSMGR_INVALID_DSCP) ? resp.return_dscp >> XT_DSCP_SHIFT : 0;
			ecvi->process_response.return_dscp = (resp.flow_dscp != OVSMGR_INVALID_DSCP) ? resp.flow_dscp >> XT_DSCP_SHIFT : ecvi->process_response.flow_dscp;
			DEBUG_TRACE("FLOW DSCP: 0x%x RETURN DSCP: 0x%x\n",
					ecvi->process_response.flow_dscp, ecvi->process_response.return_dscp);
		}
		ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_DSCP;
	}

allow_accel:
	/*
	 * Acceleration is permitted
	 */
	ecvi->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
	ecvi->process_response.process_actions |= ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
	ecvi->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_ACCEL;

	*process_response = ecvi->process_response;
	spin_unlock_bh(&ecm_classifier_ovs_lock);
	ecm_db_connection_deref(ci);
	return;

not_relevant:
	/*
	 * ecm_classifier_ovs_lock MUST be held
	 */
	spin_lock_bh(&ecm_classifier_ovs_lock);
	ecvi->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_NO;
	*process_response = ecvi->process_response;
	spin_unlock_bh(&ecm_classifier_ovs_lock);
	return;

deny_accel:
	/*
	 * ecm_classifier_ovs_lock MUST be held
	 */
	spin_lock_bh(&ecm_classifier_ovs_lock);
	ecvi->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_YES;
	ecvi->process_response.process_actions = ECM_CLASSIFIER_PROCESS_ACTION_ACCEL_MODE;
	ecvi->process_response.accel_mode = ECM_CLASSIFIER_ACCELERATION_MODE_NO;
	*process_response = ecvi->process_response;
	spin_unlock_bh(&ecm_classifier_ovs_lock);
	ecm_db_connection_deref(ci);
}

/*
 * ecm_classifier_ovs_type_get()
 *	Get type of classifier this is
 */
static ecm_classifier_type_t ecm_classifier_ovs_type_get(struct ecm_classifier_instance *aci)
{
	struct ecm_classifier_ovs_instance *ecvi;
	ecvi = (struct ecm_classifier_ovs_instance *)aci;

	DEBUG_CHECK_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC, "%px: magic failed", ecvi);
	return ECM_CLASSIFIER_TYPE_OVS;
}

/*
 * ecm_classifier_ovs_reclassify_allowed()
 *	Get whether reclassification is allowed
 */
static bool ecm_classifier_ovs_reclassify_allowed(struct ecm_classifier_instance *aci)
{
	struct ecm_classifier_ovs_instance *ecvi;
	ecvi = (struct ecm_classifier_ovs_instance *)aci;

	DEBUG_CHECK_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC, "%px: magic failed", ecvi);
	return true;
}

/*
 * ecm_classifier_ovs_reclassify()
 *	Reclassify
 */
static void ecm_classifier_ovs_reclassify(struct ecm_classifier_instance *aci)
{
	struct ecm_classifier_ovs_instance *ecvi;
	ecvi = (struct ecm_classifier_ovs_instance *)aci;
	DEBUG_CHECK_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC, "%px: magic failed", ecvi);

	/*
	 * Revert back to MAYBE relevant - we will evaluate when we get the next process() call.
	 */
	spin_lock_bh(&ecm_classifier_ovs_lock);
	ecvi->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_MAYBE;
	spin_unlock_bh(&ecm_classifier_ovs_lock);
}

/*
 * ecm_classifier_ovs_last_process_response_get()
 *	Get result code returned by the last process call
 */
static void ecm_classifier_ovs_last_process_response_get(struct ecm_classifier_instance *aci,
	struct ecm_classifier_process_response *process_response)
{
	struct ecm_classifier_ovs_instance *ecvi;
	ecvi = (struct ecm_classifier_ovs_instance *)aci;
	DEBUG_CHECK_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC, "%px: magic failed", ecvi);

	spin_lock_bh(&ecm_classifier_ovs_lock);
	*process_response = ecvi->process_response;
	spin_unlock_bh(&ecm_classifier_ovs_lock);
}

/*
 * ecm_classifier_ovs_stats_sync()
 *	Sync the stats of the OVS flow.
 */
static inline void ecm_classifier_ovs_stats_sync(struct ovsmgr_dp_flow *flow,
					  uint32_t pkts, uint32_t bytes,
					  struct net_device *indev, struct net_device *outdev,
					  uint8_t *smac, uint8_t *dmac,
					  ip_addr_t sip, ip_addr_t dip,
					  uint16_t sport, uint16_t dport, uint16_t tci, uint16_t tpid)
{
	struct ovsmgr_dp_flow_stats stats;

	flow->indev = indev;
	flow->outdev = outdev;

	ether_addr_copy(flow->smac, smac);
	ether_addr_copy(flow->dmac, dmac);

	/*
	 * Set default VLAN tci and vlan encapsulated proto.
	 */
	flow->ingress_vlan.h_vlan_TCI = 0;
	flow->ingress_vlan.h_vlan_encapsulated_proto = 0;

	if (tci) {
		flow->ingress_vlan.h_vlan_TCI = tci;
		flow->ingress_vlan.h_vlan_encapsulated_proto = tpid;
	}

	flow->tuple.src_port = sport;
	flow->tuple.dst_port = dport;

	if (flow->tuple.ip_version == 4) {
		ECM_IP_ADDR_TO_NIN4_ADDR(flow->tuple.ipv4.src, sip);
		ECM_IP_ADDR_TO_NIN4_ADDR(flow->tuple.ipv4.dst, dip);
		DEBUG_TRACE("%px: STATS: src MAC: %pM src_dev: %s src: %pI4:%d proto: %d dest: %pI4:%d dest_dev: %s dest MAC: %pM TCI: %x, TPID: %x\n",
				flow, flow->smac, flow->indev->name, &flow->tuple.ipv4.src, flow->tuple.src_port, flow->tuple.protocol,
				&flow->tuple.ipv4.dst, flow->tuple.dst_port, flow->outdev->name, flow->dmac,
				flow->ingress_vlan.h_vlan_TCI, flow->ingress_vlan.h_vlan_encapsulated_proto);
	} else {
		ECM_IP_ADDR_TO_NIN6_ADDR(flow->tuple.ipv6.src, sip);
		ECM_IP_ADDR_TO_NIN6_ADDR(flow->tuple.ipv6.dst, dip);
		DEBUG_TRACE("%px: STATS: src MAC: %pM src_dev: %s src: %pI6:%d proto: %d dest: %pI6:%d dest_dev: %s dest MAC: %pM, TCI: %x, TPID: %x\n",
				flow, flow->smac, flow->indev->name, &flow->tuple.ipv6.src, flow->tuple.src_port, flow->tuple.protocol,
				&flow->tuple.ipv6.dst, flow->tuple.dst_port, flow->outdev->name, flow->dmac,
				flow->ingress_vlan.h_vlan_TCI, flow->ingress_vlan.h_vlan_encapsulated_proto);
	}

	/*
	 * Set the flow stats and update the flow database.
	 */
	stats.pkts = pkts;
	stats.bytes = bytes;

	ovsmgr_flow_stats_update(flow, &stats);
}

#ifdef ECM_MULTICAST_ENABLE
/*
 * ecm_classifier_ovs_multicast_sync_to_stats()
 *	Common multicast sync_to function for IPv4 and IPv6.
 */
static void ecm_classifier_ovs_multicast_sync_to_stats(struct ecm_classifier_ovs_instance *ecvi,
					struct ecm_db_connection_instance *ci, struct ecm_classifier_rule_sync *sync)
{
	struct net_device *from_dev;
	struct net_device *to_ovs_port[ECM_DB_MULTICAST_IF_MAX];
	struct net_device *to_ovs_brdev[ECM_DB_MULTICAST_IF_MAX];
	struct net_device *br_dev;
	ip_addr_t src_ip;
	ip_addr_t dst_ip;
	uint8_t smac[ETH_ALEN];
	uint8_t dmac[ETH_ALEN];
	uint16_t sport;
	uint16_t dport;
	struct ovsmgr_dp_flow flow;
	int if_cnt, i, valid_ifcnt = 0, ifindex;
	uint16_t tpid = 0, tci = 0;

	/*
	 * Get the possible OVS bridge ports.
	 */
	from_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_FROM, true);
	if_cnt = ecm_interface_multicast_ovs_to_interface_get_and_ref(ci, to_ovs_port, to_ovs_brdev);
	if (!from_dev && !if_cnt) {
		DEBUG_WARN("%px: None of the from/to interfaces is OVS bridge port\n", ci);
		return;
	}

	memset(&flow, 0, sizeof(flow));

	/*
	 * IP version and protocol are common for routed and bridge flows.
	 */
	flow.tuple.ip_version = ecm_db_connection_ip_version_get(ci);
	flow.tuple.protocol = ecm_db_connection_protocol_get(ci);
	flow.is_routed = ecm_db_connection_is_routed_get(ci);
	if (!flow.is_routed) {
		/* For multicast bridge flows, ovs creates a single rule with multiple
		 * egress interfaces. We need only one egress interface to sync the flow statistics.
		 *
		 * Sync the flow direction.
		 * eth1 to eth2
		 */
		sport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM));
		dport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO));

		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM, src_ip);
		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dst_ip);

		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, smac);
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_TO, dmac);

		if (ecvi->process_response.ingress_vlan_tag[0] != ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED) {
			tci = ecvi->process_response.ingress_vlan_tag[0] & 0xffff;
			tpid = (ecvi->process_response.ingress_vlan_tag[0] >> 16) & 0xffff;
			DEBUG_TRACE("%px: Ingress VLAN : %x:%x\n", ci, tci, tpid);
		}

		ecm_classifier_ovs_stats_sync(&flow,
				sync->rx_packet_count[ECM_CONN_DIR_FLOW], sync->rx_byte_count[ECM_CONN_DIR_FLOW],
				from_dev, to_ovs_port[0],
				smac, dmac,
				src_ip, dst_ip,
				sport, dport, tci, tpid);

		goto done;
	}

	/*
	 * The 'to' interfaces ports can be part of different OVS bridges.
	 * ovs-br1-(eth0, eth1, eth2)
	 * ovs-br2-(eth3)
	 * ovs-br3 (eth4, eth5)
	 *
	 * Find unique ovs port and ovs bridge combination, as for statistics
	 * update we need only one port from each OVS bridge.
	 *
	 * The logic will derive the below output for the
	 * above mentioned ovs 'to' interface list.
	 * to_ovs_port: eth0, eth3, eth4
	 * to_ovs_brdev: ovs-br1, ovs-br2, ovs-br3
	 *
	 */
	if (if_cnt) {
		ifindex = to_ovs_brdev[0]->ifindex;
		for (i = 1, valid_ifcnt = 1; i < if_cnt; i++) {
			if (ifindex == to_ovs_brdev[i]->ifindex) {
				dev_put(to_ovs_port[i]);
				continue;
			}

			to_ovs_port[valid_ifcnt] = to_ovs_port[i];
			to_ovs_brdev[valid_ifcnt] = to_ovs_brdev[i];
			valid_ifcnt++;
		}
	}

	/*
	 * For routed flows below configurations are possible.
	 *
	 * 1. From interface is OVS bridge port, to interface is
	 * another OVS bridge port
	 * PC1 -----> eth1-ovs-br1--->ovs-br2-eth2----->PC2
	 *
	 * 2. From interface is OVS bridge port, multiple to
	 * OVS bridge port (OVS master is same).
	 * PC1 -----> eth1-ovs-br1--->ovs-br2-eth2,eth3----->PC2
	 *
	 * 3. From interface is OVS bridge port, multiple to
	 * OVS bridge port (OVS masters are different).
	 * PC1 -----> eth1-ovs-br1--->ovs-br2-eth2/ovs-br3-eth3----->PC2
	 */
	if (from_dev) {
		/*
		 * from_dev = eth1
		 * br_dev = ovs-br1
		 */
		br_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_FROM, false);
		if (!br_dev) {
			DEBUG_WARN("%px: from_dev = %s is a OVS bridge port, bridge interface is not found\n",
					ci, from_dev->name);
			goto done;
		}

		/*
		 * Sync the flow direction.
		 * eth1 to ovs-br1
		 */
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, smac);
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_TO, dmac);

		sport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM));
		dport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO));

		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM, src_ip);
		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dst_ip);

		if (ecvi->process_response.ingress_vlan_tag[0] != ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED) {
			tci = ecvi->process_response.ingress_vlan_tag[0] & 0xffff;
			tpid = (ecvi->process_response.ingress_vlan_tag[0] >> 16) & 0xffff;
			DEBUG_TRACE("%px: Ingress VLAN : %x:%x\n", ci, tci, tpid);
		}

		ecm_classifier_ovs_stats_sync(&flow,
				sync->rx_packet_count[ECM_CONN_DIR_FLOW], sync->rx_byte_count[ECM_CONN_DIR_FLOW],
				from_dev, br_dev,
				smac, dmac,
				src_ip, dst_ip,
				sport, dport, tci, tpid);
		dev_put(br_dev);
	}

	/*
	 * For routed flow, to side can be multiple OVS bridge ports and
	 * the ports can be part of different OVS bridge master.
	 *
	 * 1. outdev = eth2
	 * indev = ovs-br2
	 * Sync the flow direction.
	 * ovs-br2 to eth2
	 *
	 * 2. outdev = eth3
	 * indev = ovs-br2
	 * Sync the flow direction.
	 * ovs-br2 to eth3
	 *
	 * 3. outdev = eth3
	 * indev = ovs-br3
	 * Sync the flow direction.
	 * ovs-br3 to eth3
	 *
	 */
	ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_TO, dmac);
	ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dst_ip);
	for (i = 0; i < valid_ifcnt; i++) {
		ether_addr_copy(smac, to_ovs_brdev[i]->dev_addr);

		sport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM));
		dport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO));

		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM, src_ip);

		/*
		 * tci and tpid is 0 for pkts received from ovs bridge
		 */
		tci = tpid = 0;

		ecm_classifier_ovs_stats_sync(&flow,
				sync->rx_packet_count[ECM_CONN_DIR_FLOW], sync->rx_byte_count[ECM_CONN_DIR_FLOW],
				to_ovs_brdev[i], to_ovs_port[i],
				smac, dmac,
				src_ip, dst_ip,
				sport, dport, tci, tpid);
	}

done:
	if (from_dev)
		dev_put(from_dev);

	for (i = 0; i < valid_ifcnt; i++) {
		dev_put(to_ovs_port[i]);
	}
}
#endif

/*
 * ecm_classifier_ovs_sync_to_stats()
 *	Common sync_to function for IPv4 and IPv6.
 */
static void ecm_classifier_ovs_sync_to_stats(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_sync *sync)
{
	ip_addr_t src_ip;
	ip_addr_t dst_ip;
	struct ecm_db_connection_instance *ci;
	struct ovsmgr_dp_flow flow;
	struct net_device *from_dev;
	struct net_device *to_dev;
	struct net_device *br_dev;
	uint8_t smac[ETH_ALEN];
	uint8_t dmac[ETH_ALEN];
	uint16_t sport;
	uint16_t dport;
	uint16_t tpid = 0, tci = 0;

	struct ecm_classifier_ovs_instance *ecvi = (struct ecm_classifier_ovs_instance *)aci;

	DEBUG_CHECK_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC, "%px: magic failed", ecvi);

	ci = ecm_db_connection_serial_find_and_ref(ecvi->ci_serial);
	if (!ci) {
		DEBUG_TRACE("%px: No ci found for %u\n", ecvi, ecvi->ci_serial);
		return;
	}

#ifdef ECM_MULTICAST_ENABLE
	/*
	 * Check for multicast connection.
	 */
	ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dst_ip);
	if (ecm_ip_addr_is_multicast(dst_ip)) {
		ecm_classifier_ovs_multicast_sync_to_stats(ecvi, ci, sync);
		ecm_db_connection_deref(ci);
		return;
	}
#endif
	memset(&flow, 0, sizeof(flow));

	/*
	 * Get the possible OVS bridge ports.
	 */
	from_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_FROM, true);
	to_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_TO, true);

	/*
	 * IP version and protocol are common for routed and bridge flows.
	 */
	flow.tuple.ip_version = ecm_db_connection_ip_version_get(ci);
	flow.tuple.protocol = ecm_db_connection_protocol_get(ci);
	flow.is_routed = ecm_db_connection_is_routed_get(ci);

	/*
	 * Get the tci and tpid values of the ingress side of the flow.
	 */
	if (ecvi->process_response.ingress_vlan_tag[0] != ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED) {
		tci = ecvi->process_response.ingress_vlan_tag[0] & 0xffff;
		tpid = (ecvi->process_response.ingress_vlan_tag[0] >> 16) & 0xffff;
		DEBUG_TRACE("%px: Ingress VLAN : %x:%x\n", aci, tci, tpid);
	}

	/*
	 * Bridge flow
	 */
	if (!flow.is_routed) {
		/*
		 * Sync the flow direction (eth1 to eth2)
		 *
		 * ECM depends on netdev private flags to identify
		 * if it is an OVS port, if the port is removed from
		 * bridge while traffic is running then the device is
		 * not part of bridge.  Do not update statistics if ports
		 * are removed from bridge.
		 */
		if (!from_dev || !to_dev) {
			ecm_db_connection_deref(ci);
			return;
		}

		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, smac);
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_TO, dmac);

		sport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM));
		dport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO));

		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM, src_ip);
		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dst_ip);

		DEBUG_TRACE("%px: Flow direction stats update\n", aci);
		ecm_classifier_ovs_stats_sync(&flow,
				  sync->rx_packet_count[ECM_CONN_DIR_FLOW], sync->rx_byte_count[ECM_CONN_DIR_FLOW],
				  from_dev, to_dev,
				  smac, dmac,
				  src_ip, dst_ip,
				  sport, dport, tci, tpid);

		/*
		 * Sync the return direction (eth2 to eth1)
		 * All the flow parameters are reversed.
		 */
		DEBUG_TRACE("%px: Return direction stats update\n", aci);

		/*
		 * Reset the tci and tpid values and get the egress side of the flow.
		 */
		tci = tpid = 0;
		if (ecvi->process_response.egress_vlan_tag[0] != ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED) {
			tci = ecvi->process_response.egress_vlan_tag[0] & 0xffff;
			tpid = (ecvi->process_response.egress_vlan_tag[0] >> 16) & 0xffff;
			DEBUG_TRACE("%px: Egress VLAN : %x:%x\n", aci, tci, tpid);
		}

		ecm_classifier_ovs_stats_sync(&flow,
				  sync->rx_packet_count[ECM_CONN_DIR_RETURN], sync->rx_byte_count[ECM_CONN_DIR_RETURN],
				  to_dev, from_dev,
				  dmac, smac,
				  dst_ip, src_ip,
				  dport, sport, tci, tpid);
		goto done;
	}

	/*
	 * For routed flows both from and to side can be OVS bridge port, if there
	 * is a routed flow between two OVS bridges. (e.g: ovs-br1 and ovs-br2)
	 *
	 * These are the netdevice places and the IP address values based on the
	 * 4 different NAT cases.
	 *
	 * SNAT:
	 * PC1 -----> eth1-ovs-br1--->ovs-br2-eth2 -----> PC2
	 *		(from_dev)	(to_dev)
	 * src_ip			src_ip_nat	dest_ip/dest_ip_nat
	 *
	 * DNAT
	 * PC1 <----- eth1-ovs-br1<---ovs-br2-eth2 <----- PC2
	 *		(to_dev)	(from_dev)
	 * dest_ip			dest_ip_nat	src_ip/src_ip_nat
	 *
	 * Non-NAT - Egress
	 * PC1 -----> eth1-ovs-br1--->ovs-br2-eth2 -----> PC2
	 *		(from_dev)	(to_dev)
	 * src_ip/src_ip_nat				dest_ip/dest_ip_nat
	 *
	 * Non-NAT - Ingress
	 * PC1 <----- eth1-ovs-br1<---ovs-br2-eth2 <----- PC2
	 *		(to_dev)	(from_dev)
	 * dest_ip/dest_ip_nat				src_ip/src_ip_nat
	 */
	if (from_dev) {
		/*
		 * from_dev = eth1/eth2  (can be tagged)
		 * br_dev = ovs-br1/ovs_br2 (untagged)
		 */
		br_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_FROM, false);
		if (!br_dev) {
			DEBUG_WARN("%px: from_dev = %s is a OVS bridge port, bridge interface is not found\n",
					aci, from_dev->name);
			goto done;
		}

		/*
		 * Sync the flow direction (eth1/eth2 to ovs-br1/ovs_br2) based on the NAT case.
		 */
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, smac);
		ether_addr_copy(dmac, br_dev->dev_addr);

		/*
		 * If from_dev is a bridge port, dest_ip_nat and dest_port_nat satisfies all the NAT cases.
		 * So, we need to get the ECM_DB_OBJ_DIR_TO_NAT direction's IP and port number from the connection.
		 */
		sport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM));
		dport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO_NAT));

		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM, src_ip);
		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO_NAT, dst_ip);

		ecm_classifier_ovs_stats_sync(&flow,
				  sync->rx_packet_count[ECM_CONN_DIR_FLOW], sync->rx_byte_count[ECM_CONN_DIR_FLOW],
				  from_dev, br_dev,
				  smac, dmac,
				  src_ip, dst_ip,
				  sport, dport, tci, tpid);

		/*
		 * Sync the return direction (ovs-br1/ovs_br2 to eth1/eth2) based on the NAT case.
		 * All the flow parameters are reversed.
		 */
		ecm_classifier_ovs_stats_sync(&flow,
				  sync->tx_packet_count[ECM_CONN_DIR_FLOW], sync->tx_byte_count[ECM_CONN_DIR_FLOW],
				  br_dev, from_dev,
				  dmac, smac,
				  dst_ip, src_ip,
				  dport, sport, 0, 0);
		dev_put(br_dev);
	}

	if (to_dev) {
		/*
		 * to_dev = eth2/eth1 (can be tagged)
		 * br_dev = ovs-br2/ovs-br1 (untagged)
		 */
		br_dev = ecm_classifier_ovs_interface_get_and_ref(ci, ECM_DB_OBJ_DIR_TO, false);
		if (!br_dev) {
			DEBUG_WARN("%px: to_dev = %s is a OVS bridge port, bridge interface is not found\n",
					aci, to_dev->name);
			goto done;
		}

		/*
		 * Reset the tci and tpid values and get the egress side of the flow.
		 */
		tci = tpid = 0;
		if (ecvi->process_response.egress_vlan_tag[0] != ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED) {
			tci = ecvi->process_response.egress_vlan_tag[0] & 0xffff;
			tpid = (ecvi->process_response.egress_vlan_tag[0] >> 16) & 0xffff;
			DEBUG_TRACE("%px: Egress VLAN : %x:%x\n", aci, tci, tpid);
		}

		/*
		 * Sync the flow direction (ovs-br2/ovs_br1 to eth2/eth1) based on the NAT case.
		 */
		ether_addr_copy(smac, br_dev->dev_addr);
		ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_TO, dmac);

		/*
		 * If to_dev is a bridge port, src_ip_nat and src_port_nat satisfies all the NAT cases.
		 * So, we need to get the ECM_DB_OBJ_DIR_FROM_NAT direction's IP and port number from the connection.
		 */
		sport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_FROM_NAT));
		dport = htons(ecm_db_connection_port_get(ci, ECM_DB_OBJ_DIR_TO));

		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_FROM_NAT, src_ip);
		ecm_db_connection_address_get(ci, ECM_DB_OBJ_DIR_TO, dst_ip);

		ecm_classifier_ovs_stats_sync(&flow,
				  sync->tx_packet_count[ECM_CONN_DIR_RETURN], sync->tx_byte_count[ECM_CONN_DIR_RETURN],
				  br_dev, to_dev,
				  smac, dmac,
				  src_ip, dst_ip,
				  sport, dport, 0, 0);
		/*
		 * Sync the return direction (eth2/eth1 to ovs-br2/ovs-br1) based on the NAT case.
		 * All the flow parameters are reversed.
		 */
		ecm_classifier_ovs_stats_sync(&flow,
				  sync->rx_packet_count[ECM_CONN_DIR_RETURN], sync->rx_byte_count[ECM_CONN_DIR_RETURN],
				  to_dev, br_dev,
				  dmac, smac,
				  dst_ip, src_ip,
				  dport, sport, tci, tpid);
		dev_put(br_dev);
	}

done:
	ecm_db_connection_deref(ci);

	if (from_dev)
		dev_put(from_dev);
	if (to_dev)
		dev_put(to_dev);
}

/*
 * ecm_classifier_ovs_sync_to_v4()
 *	Front end is pushing accel engine state to us
 */
static void ecm_classifier_ovs_sync_to_v4(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_sync *sync)
{
	/*
	 * Nothing to update.
	 * We only care about flows that are actively being accelerated.
	 */
	if (!(sync->tx_packet_count[ECM_CONN_DIR_FLOW] || sync->tx_packet_count[ECM_CONN_DIR_RETURN])) {
		return;
	}

	/*
	 * Handle only the stats sync. We don't care about the evict or flush syncs.
	 */
	if (sync->reason != ECM_FRONT_END_IPV4_RULE_SYNC_REASON_STATS) {
		return;
	}

	/*
	 * Common sync_to function call.
	 */
	ecm_classifier_ovs_sync_to_stats(aci, sync);
}

/*
 * ecm_classifier_ovs_sync_from_v4()
 *	Front end is retrieving accel engine state from us
 */
static void ecm_classifier_ovs_sync_from_v4(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_create *ecrc)
{
	struct ecm_classifier_ovs_instance *ecvi __attribute__((unused));

	ecvi = (struct ecm_classifier_ovs_instance *)aci;
	DEBUG_CHECK_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC, "%px: magic failed", ecvi);
}

/*
 * ecm_classifier_ovs_sync_to_v6()
 *	Front end is pushing accel engine state to us
 */
static void ecm_classifier_ovs_sync_to_v6(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_sync *sync)
{
	/*
	 * Nothing to update.
	 * We only care about flows that are actively being accelerated.
	 */
	if (!(sync->tx_packet_count[ECM_CONN_DIR_FLOW] || sync->tx_packet_count[ECM_CONN_DIR_RETURN])) {
		return;
	}

	/*
	 * Handle only the stats sync. We don't care about the evict or flush syncs.
	 */
	if (sync->reason != ECM_FRONT_END_IPV6_RULE_SYNC_REASON_STATS) {
		return;
	}

	/*
	 * Common sync_to function call.
	 */
	ecm_classifier_ovs_sync_to_stats(aci, sync);
}

/*
 * ecm_classifier_ovs_sync_from_v6()
 *	Front end is retrieving accel engine state from us
 */
static void ecm_classifier_ovs_sync_from_v6(struct ecm_classifier_instance *aci, struct ecm_classifier_rule_create *ecrc)
{
	struct ecm_classifier_ovs_instance *ecvi __attribute__((unused));

	ecvi = (struct ecm_classifier_ovs_instance *)aci;
	DEBUG_CHECK_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC, "%px: magic failed", ecvi);
}

#ifdef ECM_STATE_OUTPUT_ENABLE
/*
 * ecm_classifier_ovs_state_get()
 *	Gets the state of this classfier and outputs it to debugfs.
 */
static int ecm_classifier_ovs_state_get(struct ecm_classifier_instance *ci, struct ecm_state_file_instance *sfi)
{
	int result;
	struct ecm_classifier_ovs_instance *ecvi;
	struct ecm_classifier_process_response pr;

	ecvi = (struct ecm_classifier_ovs_instance *)ci;
	DEBUG_CHECK_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC, "%px: magic failed", ecvi);

	if ((result = ecm_state_prefix_add(sfi, "ovs"))) {
		return result;
	}

	spin_lock_bh(&ecm_classifier_ovs_lock);
	pr = ecvi->process_response;
	spin_unlock_bh(&ecm_classifier_ovs_lock);

	/*
	 * Output our last process response
	 */
	if ((result = ecm_classifier_process_response_state_get(sfi, &pr))) {
		goto done;
	}


	if (pr.process_actions & ECM_CLASSIFIER_PROCESS_ACTION_OVS_VLAN_TAG) {
#ifdef ECM_MULTICAST_ENABLE
		int i;
#endif
		/*
		 * TODO: Clean up the function later to print classifier
		 * specific data in each classifier’s state_get function.
		 */
		if (pr.ingress_vlan_tag[0] != ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED) {
			if ((result = ecm_state_write(sfi, "ingress_vlan_tag[0]", "0x%x", pr.ingress_vlan_tag[0]))) {
				goto done;
			}
		}

		if (pr.ingress_vlan_tag[1] != ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED) {
			if ((result = ecm_state_write(sfi, "ingress_vlan_tag[1]", "0x%x", pr.ingress_vlan_tag[1]))) {
				goto done;
			}
		}

		if (pr.egress_vlan_tag[0] != ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED) {
			if ((result = ecm_state_write(sfi, "egress_vlan_tag[0]", "0x%x", pr.egress_vlan_tag[0]))) {
				goto done;
			}
		}

		if (pr.egress_vlan_tag[1] != ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED) {
			if ((result = ecm_state_write(sfi, "egress_vlan_tag[1]", "0x%x", pr.egress_vlan_tag[1]))) {
				goto done;
			}
		}

#ifdef ECM_MULTICAST_ENABLE
		for (i = 0; i < ECM_DB_MULTICAST_IF_MAX; i++) {
			struct net_device *dev;

			if (pr.egress_mc_vlan_tag[i][0] == ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED) {
				continue;
			}

			dev = dev_get_by_index(&init_net, pr.egress_netdev_index[i]);
			if (dev) {
				if ((result = ecm_state_write(sfi, "port_egress", "%s", dev->name))) {
					dev_put(dev);
					goto done;
				}
				dev_put(dev);
			}

			if ((result = ecm_state_write(sfi, "port_egress_vlan_tag[0]", "0x%x", pr.egress_mc_vlan_tag[i][0]))) {
				goto done;
			}

			if (pr.egress_mc_vlan_tag[i][1] != ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED) {
				if ((result = ecm_state_write(sfi, "port_egress_vlan_tag[1]", "0x%x", pr.egress_mc_vlan_tag[i][1]))) {
					goto done;
				}
			}
		}
#endif
	}

done:
	ecm_state_prefix_remove(sfi);
	return result;
}
#endif

/*
 * ecm_classifier_ovs_instance_alloc()
 *	Allocate an instance of the ovs classifier
 */
struct ecm_classifier_ovs_instance *ecm_classifier_ovs_instance_alloc(struct ecm_db_connection_instance *ci)
{
	struct ecm_classifier_ovs_instance *ecvi;
#ifdef ECM_MULTICAST_ENABLE
	int i;
#endif

	/*
	 * Allocate the instance
	 */
	ecvi = (struct ecm_classifier_ovs_instance *)kzalloc(sizeof(struct ecm_classifier_ovs_instance), GFP_ATOMIC | __GFP_NOWARN);
	if (!ecvi) {
		DEBUG_WARN("i%px: Failed to allocate ovs Classifier instance\n", ci);
		return NULL;
	}

	DEBUG_SET_MAGIC(ecvi, ECM_CLASSIFIER_OVS_INSTANCE_MAGIC);
	ecvi->refs = 1;

	/*
	 * Methods generic to all classifiers.
	 */
	ecvi->base.process = ecm_classifier_ovs_process;
	ecvi->base.sync_from_v4 = ecm_classifier_ovs_sync_from_v4;
	ecvi->base.sync_to_v4 = ecm_classifier_ovs_sync_to_v4;
	ecvi->base.sync_from_v6 = ecm_classifier_ovs_sync_from_v6;
	ecvi->base.sync_to_v6 = ecm_classifier_ovs_sync_to_v6;
	ecvi->base.type_get = ecm_classifier_ovs_type_get;
	ecvi->base.reclassify_allowed = ecm_classifier_ovs_reclassify_allowed;
	ecvi->base.reclassify = ecm_classifier_ovs_reclassify;
	ecvi->base.last_process_response_get = ecm_classifier_ovs_last_process_response_get;
#ifdef ECM_STATE_OUTPUT_ENABLE
	ecvi->base.state_get = ecm_classifier_ovs_state_get;
#endif
	ecvi->base.ref = ecm_classifier_ovs_ref;
	ecvi->base.deref = ecm_classifier_ovs_deref;
	ecvi->ci_serial = ecm_db_connection_serial_get(ci);

	ecvi->process_response.process_actions = 0;
	ecvi->process_response.relevance = ECM_CLASSIFIER_RELEVANCE_MAYBE;
	ecvi->process_response.ingress_vlan_tag[0] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
	ecvi->process_response.egress_vlan_tag[0] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
	ecvi->process_response.ingress_vlan_tag[1] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
	ecvi->process_response.egress_vlan_tag[1] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;

#ifdef ECM_MULTICAST_ENABLE
	for (i = 0; i < ECM_DB_MULTICAST_IF_MAX; i++) {
		ecvi->process_response.egress_mc_vlan_tag[i][0] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
		ecvi->process_response.egress_mc_vlan_tag[i][1] = ECM_FRONT_END_VLAN_ID_NOT_CONFIGURED;
	}
#endif

	/*
	 * Final check if we are pending termination
	 */
	spin_lock_bh(&ecm_classifier_ovs_lock);
	if (ecm_classifier_ovs_terminate_pending) {
		spin_unlock_bh(&ecm_classifier_ovs_lock);
		DEBUG_WARN("%px: Terminating\n", ci);
		kfree(ecvi);
		return NULL;
	}

	/*
	 * Link the new instance into our list at the head
	 */
	ecvi->next = ecm_classifier_ovs_instances;
	if (ecm_classifier_ovs_instances) {
		ecm_classifier_ovs_instances->prev = ecvi;
	}
	ecm_classifier_ovs_instances = ecvi;

	/*
	 * Increment stats
	 */
	ecm_classifier_ovs_count++;
	DEBUG_ASSERT(ecm_classifier_ovs_count > 0, "%px: ecm_classifier_ovs_count wrap for instance: %px\n", ci, ecvi);
	spin_unlock_bh(&ecm_classifier_ovs_lock);

	DEBUG_INFO("%px: ovs classifier instance alloc: %px\n", ci, ecvi);
	return ecvi;
}
EXPORT_SYMBOL(ecm_classifier_ovs_instance_alloc);

/*
 * ecm_classifier_ovs_register_callbacks()
 */
int ecm_classifier_ovs_register_callbacks(struct ecm_classifier_ovs_callbacks *ovs_cbs)
{
	spin_lock_bh(&ecm_classifier_ovs_lock);

	if (unlikely(!ecm_classifier_ovs_enabled)) {
		spin_unlock_bh(&ecm_classifier_ovs_lock);
		return -1;
	}

	ovs.ovs_process = ovs_cbs->ovs_process;
	spin_unlock_bh(&ecm_classifier_ovs_lock);

	return 0;
}
EXPORT_SYMBOL(ecm_classifier_ovs_register_callbacks);

/*
 * ecm_classifier_ovs_unregister_callbacks()
 */
void ecm_classifier_ovs_unregister_callbacks(void)
{
	spin_lock_bh(&ecm_classifier_ovs_lock);
	ovs.ovs_process = NULL;
	spin_unlock_bh(&ecm_classifier_ovs_lock);
}
EXPORT_SYMBOL(ecm_classifier_ovs_unregister_callbacks);

/*
 * ecm_classifier_ovs_init()
 */
int ecm_classifier_ovs_init(struct dentry *dentry)
{
	DEBUG_INFO("ovs classifier Module init\n");

	ecm_classifier_ovs_dentry = debugfs_create_dir("ecm_classifier_ovs", dentry);
	if (!ecm_classifier_ovs_dentry) {
		DEBUG_ERROR("Failed to create ecm ovs directory in debugfs\n");
		return -1;
	}

	if (!debugfs_create_u32("enabled", S_IRUGO | S_IWUSR, ecm_classifier_ovs_dentry,
					(u32 *)&ecm_classifier_ovs_enabled)) {
		DEBUG_ERROR("Failed to create ovs enabled file in debugfs\n");
		debugfs_remove_recursive(ecm_classifier_ovs_dentry);
		return -1;
	}

	return 0;
}
EXPORT_SYMBOL(ecm_classifier_ovs_init);

/*
 * ecm_classifier_ovs_exit()
 */
void ecm_classifier_ovs_exit(void)
{
	DEBUG_INFO("ovs classifier Module exit\n");

	spin_lock_bh(&ecm_classifier_ovs_lock);
	ecm_classifier_ovs_terminate_pending = true;
	spin_unlock_bh(&ecm_classifier_ovs_lock);

	/*
	 * Remove the debugfs files recursively.
	 */
	if (ecm_classifier_ovs_dentry) {
		debugfs_remove_recursive(ecm_classifier_ovs_dentry);
	}

}
EXPORT_SYMBOL(ecm_classifier_ovs_exit);
