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

/*
 * ovsmgr_dp.c
 */

#include <asm/atomic.h>
#include <linux/etherdevice.h>

/*
 * OpenVSwitch header files
 */
#include <datapath.h>
#include "ovsmgr.h"
#include "ovsmgr_priv.h"

/*
 * ovsmgr_dp_find()
 *	Find datapath instance.
 *
 * This function should be called under read_lock.
 */
static struct ovsmgr_dp *ovsmgr_dp_find(void *dp)
{
	struct ovsmgr_dp *nod;

	list_for_each_entry(nod, &ovsmgr_ctx.dp_list, node) {
		if (nod->dp == dp) {
			return nod;
		}
	}

	return NULL;
}

/*
 * ovsmgr_dp_port_find_by_dev()
 *	Find datapath instance using dev.
 *
 * This function should be called under read_lock
 */
static struct ovsmgr_dp_port *ovsmgr_dp_port_find_by_dev(struct ovsmgr_dp *nod, struct net_device *dev)
{
	struct ovsmgr_dp_port *nodp;

	list_for_each_entry(nodp, &nod->port_list, node) {
		if (nodp->dev == dev) {
			return nodp;
		}
	}

	return NULL;
}

/*
 * ovsmgr_dp_port_find_by_num()
 *	Find datapath port instance using port number and datapath instance.
 *
 * This function should be called under read_lock
 */
static struct ovsmgr_dp_port *ovsmgr_dp_port_find_by_num(struct ovsmgr_dp *nod, int vport_num)
{
	struct ovsmgr_dp_port *nodp;

	list_for_each_entry(nodp, &nod->port_list, node) {
		if (nodp->vport_num == vport_num) {
			return nodp;
		}
	}

	return NULL;
}

/*
 * ovsmgr_dp_find_by_port()
 *	Find datapath instance using port number.
 *
 * This function should be called under read_lock
 */
static struct ovsmgr_dp *ovsmgr_dp_find_by_port(int vport_num)
{
	struct ovsmgr_dp_port *nodp;
	struct ovsmgr_dp *nod;

	list_for_each_entry(nod, &ovsmgr_ctx.dp_list, node) {
		nodp = ovsmgr_dp_port_find_by_num(nod, vport_num);
		if (nodp) {
			return nod;
		}
	}

	return NULL;
}

/*
 * ovsmgr_dp_find_by_dev()
 *	Find datapath instance using dev.
 *
 * This function should be called under read_lock
 */
static struct ovsmgr_dp *ovsmgr_dp_find_by_dev(struct net_device *dev)
{
	struct ovsmgr_dp_port *nodp;
	struct ovsmgr_dp *nod;

	list_for_each_entry(nod, &ovsmgr_ctx.dp_list, node) {
		nodp = ovsmgr_dp_port_find_by_dev(nod, dev);
		if (nodp) {
			return nod;
		}
	}

	return NULL;
}

/*
 * ovsmgr_dp_send_ports_add_notifier
 *	Notify port add event
 *
 * Send port add notifiers Return the first output interface in the actions.
 */
static void ovsmgr_dp_send_ports_add_notifier(struct ovsmgr_dp *nod, struct net_device *master_dev)
{
	struct ovsmgr_dp_port *nodp;
	struct ovsmgr_dp_port_info port;
	struct ovsmgr_notifiers_info info;

	list_for_each_entry(nodp, &nod->port_list, node) {
		if (!strncmp(nodp->master_name, master_dev->name, IFNAMSIZ) &&
			    !nodp->add_notified) {
			nodp->add_notified = true;
			nodp->master_dev = master_dev;
			port.master = master_dev;
			port.dev = nodp->dev;
			info.port = &port;
			ovsmgr_notifiers_call(&info, OVSMGR_DP_PORT_ADD);
		}
	}
}

/*
 * ovsmgr_dp_flow_key_dump()
 *	Dump flow key
 */
static void ovsmgr_dp_flow_key_dump(struct sw_flow_key *key)
{
	int i;

	ovsmgr_trace("Phy:\n");
	ovsmgr_trace("\tpriority = %u\n", key->phy.priority);
	ovsmgr_trace("\tskb_mark = %u\n", key->phy.skb_mark);
	ovsmgr_trace("\tin_port = %u\n", key->phy.in_port);

	ovsmgr_trace("Flow Hash = %u\n", key->ovs_flow_hash);
	ovsmgr_trace("Recirc_id = %u\n", key->recirc_id);
	ovsmgr_trace("Eth:\n");
	ovsmgr_trace("\tsmac = %pM\n", &key->eth.src);
	ovsmgr_trace("\tdmac = %pM\n", &key->eth.dst);
	ovsmgr_trace("\ttype = %x\n", key->eth.type);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
	ovsmgr_trace("\tcvlan tci = %x\n", OVSMGR_KEY_CVLAN_TCI(key));
#endif
	ovsmgr_trace("\tvlan tci = %x\n", OVSMGR_KEY_VLAN_TCI(key));

	ovsmgr_trace("IP:\n");
	ovsmgr_trace("\tproto = %d\n", key->ip.proto);
	ovsmgr_trace("\ttos = %d\n", key->ip.tos);
	ovsmgr_trace("\tttl = %d\n", key->ip.ttl);

	ovsmgr_trace("\tfrag = %d\n", key->ip.frag);

	ovsmgr_trace("TCP/UDP:\n");
	ovsmgr_trace("\tsrc = %x\n", key->tp.src);
	ovsmgr_trace("\tdst = %x\n", key->tp.dst);
	ovsmgr_trace("\tflags = %x\n", key->tp.flags);

	if (key->eth.type == htons(ETH_P_IP)) {
		ovsmgr_trace("IPv4:\n");
		ovsmgr_trace("\tsrc ip = %pI4\n", &key->ipv4.addr.src);
		ovsmgr_trace("\tdst ip = %pI4\n", &key->ipv4.addr.dst);
	} else if (key->eth.type == htons(ETH_P_IPV6)) {
		ovsmgr_trace("IPv6:\n");
		ovsmgr_trace("\tsrc ip = %pI6\n", &key->ipv6.addr.src);
		ovsmgr_trace("\tdst ip = %pI6\n", &key->ipv6.addr.dst);
	} else {
		ovsmgr_trace("Eth type = %x\n", key->eth.type);
	}

	ovsmgr_trace("CT:\n");
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
	ovsmgr_trace("\tzone = %x\n", key->ct.zone);
	ovsmgr_trace("\tstate = %x\n", key->ct.state);
#else
	ovsmgr_trace("\tzone = %x\n", key->ct_zone);
	ovsmgr_trace("\tstate = %x\n", key->ct_state);
#endif

	ovsmgr_trace("\tmark = %x\n", key->ct.mark);
	ovsmgr_trace("\tlabel: ");
	for (i = 0 ; i < OVS_CT_LABELS_LEN ; i++) {
		ovsmgr_trace("%x ", key->ct.labels.ct_labels[i]);
	}
}

/*
 * ovsmgr_dp_flow_mask_dump()
 *	Dump flow mask
 */
static void ovsmgr_dp_flow_mask_dump(struct sw_flow_mask *mask)
{
	ovsmgr_trace("ref_count = %d\n", mask->ref_count);
	ovsmgr_trace("Range:\n");
	ovsmgr_trace("\tstart = %d\n", mask->range.start);
	ovsmgr_trace("\tend = %d\n", mask->range.end);
}

/*
 * ovsmgr_dp_flow_actions_dump()
 *	Dump flow actions
 */
static void ovsmgr_dp_flow_actions_dump(struct sw_flow_actions *acts)
{
	const struct nlattr *a;
	int rem;

	for (a = acts->actions, rem = acts->actions_len; rem > 0;
	     a = nla_next(a, &rem)) {

		switch (nla_type(a)) {
		case OVS_ACTION_ATTR_OUTPUT:
			ovsmgr_trace("OVS_ACTION_ATTR_OUTPUT: Port = %d\n", nla_get_u32(a));
			break;

		case OVS_ACTION_ATTR_USERSPACE:
			ovsmgr_trace("OVS_ACTION_ATTR_USERSPACE\n");
			break;

		case OVS_ACTION_ATTR_HASH:
			ovsmgr_trace("OVS_ACTION_ATTR_HASH\n");
			break;

		case OVS_ACTION_ATTR_PUSH_MPLS:
			ovsmgr_trace("OVS_ACTION_ATTR_PUSH_MPLS\n");
			break;

		case OVS_ACTION_ATTR_POP_MPLS:
			ovsmgr_trace("OVS_ACTION_ATTR_POP_MPLS\n");
			break;

		case OVS_ACTION_ATTR_PUSH_VLAN: {
			const struct ovs_action_push_vlan *vlan;

			ovsmgr_trace("OVS_ACTION_ATTR_PUSH_VLAN\n");
			vlan = nla_data(a);
			ovsmgr_trace("Vlan details:\n");
			ovsmgr_trace("\tvlan_tpid = %x\n", vlan->vlan_tpid);
			ovsmgr_trace("\tvlan_tci = %x\n", vlan->vlan_tci);
			break;
		}

		case OVS_ACTION_ATTR_POP_VLAN:
			ovsmgr_trace("OVS_ACTION_ATTR_POP_VLAN\n");
			break;

		case OVS_ACTION_ATTR_RECIRC:
			ovsmgr_trace("OVS_ACTION_ATTR_RECIRC\n");
			break;

		case OVS_ACTION_ATTR_SET:
			ovsmgr_trace("OVS_ACTION_ATTR_SET\n");
			break;

		case OVS_ACTION_ATTR_SET_MASKED:
			ovsmgr_trace("OVS_ACTION_ATTR_SET_MASKED\n");
			break;

		case OVS_ACTION_ATTR_SET_TO_MASKED:
			ovsmgr_trace("OVS_ACTION_ATTR_SET_TO_MASKED\n");
			break;

		case OVS_ACTION_ATTR_SAMPLE:
			ovsmgr_trace("OVS_ACTION_ATTR_SAMPLE\n");
			break;

		case OVS_ACTION_ATTR_CT:
			ovsmgr_trace("OVS_ACTION_ATTR_CT\n");
			break;
		default:
			ovsmgr_trace("Unknown action: %d\n", nla_type(a));
		}
	}
}

/*
 * ovsmgr_dp_flow_dump()
 *	Dump flow details
 */
static void ovsmgr_dp_flow_dump(struct sw_flow *flow)
{
	struct sw_flow_actions *acts;

	ovsmgr_trace("------- Flow Key --------\n");
	ovsmgr_dp_flow_key_dump(&flow->key);

	ovsmgr_trace("------- Flow Mask --------\n");
	ovsmgr_dp_flow_mask_dump(flow->mask);

	acts = rcu_dereference(flow->sf_acts);
	ovsmgr_trace("------- Flow Actions ------\n");
	ovsmgr_dp_flow_actions_dump(acts);
}

/*
 * ovsmgr_dp_mcast_port_dev_find()
 *	Find egress datapath port, given skb and datapath interface (dev)
 */
static struct net_device *ovsmgr_dp_mcast_port_dev_find(struct ovsmgr_dp *nod,
							    struct ovsmgr_dp_port *master,
							    struct ovsmgr_dp_flow *flow, struct sk_buff *skb)
{
	struct ovsmgr_dp_port *p;
	struct sw_flow_key key;
	struct net_device *dev;

	/*
	 * For multicast flow there is only one flow rule in datapath.  In case
	 * of multicast routing flow there is no flow from OVS bridge interface
	 * to bridge port.  The only way is to search for all the ports that are
	 * part of bridge.
	 *
	 * Create a originate flow key
	 */
	memset(&key, 0, sizeof(key));
	ether_addr_copy(key.eth.src, flow->smac);
	ether_addr_copy(key.eth.dst, flow->dmac);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
	key.mac_proto = MAC_PROTO_ETHERNET;
#endif

	if (flow->tuple.ip_version == 4) {
		key.ipv4.addr.src = flow->tuple.ipv4.src;
		key.ipv4.addr.dst = flow->tuple.ipv4.dst;
		key.eth.type = htons(ETH_P_IP);
	} else {
		memcpy(&key.ipv6.addr.src, &flow->tuple.ipv6.src, sizeof(key.ipv6.addr.src));
		memcpy(&key.ipv6.addr.dst, &flow->tuple.ipv6.dst, sizeof(key.ipv6.addr.dst));
		key.eth.type = htons(ETH_P_IPV6);
	}

	key.tp.src = flow->tuple.src_port;
	key.tp.dst = flow->tuple.dst_port;
	key.ip.proto = flow->tuple.protocol;

	read_lock(&ovsmgr_ctx.lock);
	list_for_each_entry(p, &nod->port_list, node) {
		/*
		 * Skip search if the port is not part of same bridge
		 */
		if (p->master_dev != master->dev) {
			continue;
		}

		key.phy.in_port = p->vport_num;
		dev = ovs_accel_egress_dev_find(nod->dp, &key, skb);
		if (dev) {
			read_unlock(&ovsmgr_ctx.lock);
			ovsmgr_info("%px: Found the egress interface for this flow, returning ingress port: %s\n",
					nod, p->dev->name);
			return p->dev;
		}
	}

	read_unlock(&ovsmgr_ctx.lock);
	return NULL;
}

/*
 * ovsmgr_dp_is_ipv6_mask_nonzero()
 *	Return true if ip_addr is non-zero
 */
static inline bool ovsmgr_dp_is_ipv6_mask_nonzero(const uint32_t ip_addr[4])
{
	return !!(ip_addr[0] | ip_addr[1] | ip_addr[2] | ip_addr[3]);
}

/*
 * ovsmgr_dp_ipv6_mask_addr()
 *	Calculate masked IPv6 address and copy in new_addr
 */
static inline void ovsmgr_dp_ipv6_mask_addr(const __be32 old_addr[4], const __be32 v6_addr[4],
			   const __be32 v6_mask[4], __be32 new_addr[4])
{
	new_addr[0] = OVS_MASKED(old_addr[0], v6_addr[0], v6_mask[0]);
	new_addr[1] = OVS_MASKED(old_addr[1], v6_addr[1], v6_mask[1]);
	new_addr[2] = OVS_MASKED(old_addr[2], v6_addr[2], v6_mask[2]);
	new_addr[3] = OVS_MASKED(old_addr[3], v6_addr[3], v6_mask[3]);
}

/*
 * ovsmgr_dp_eth_mask_addr()
 *	Calculate masked MAC address and copy in new_mac
 */
static inline void ovsmgr_dp_eth_mask_addr(const u8 *old_mac, const u8 *mac, const u8 *mac_mask, u8 *new_mac)
{
	u16 *nmac = (u16 *)new_mac;
	const u16 *omac = (const u16 *)old_mac;
	const u16 *tmp_mac = (const u16 *)mac;
	const u16 *tmp_mask = (const u16 *)mac_mask;

	nmac[0] = OVS_MASKED(omac[0], tmp_mac[0], tmp_mask[0]);
	nmac[1] = OVS_MASKED(omac[1], tmp_mac[1], tmp_mask[1]);
	nmac[2] = OVS_MASKED(omac[2], tmp_mac[2], tmp_mask[2]);
}

/*
 * ovsmgr_dp_action_set_mask_get_dscp()
 *	Return DSCP value configured in flow rule
 */
static int ovsmgr_dp_action_set_mask_get_dscp(struct sw_flow_key *key, const struct nlattr *a)
{
	switch (nla_type(a)) {
	case OVS_KEY_ATTR_IPV4: {
		const struct ovs_key_ipv4 *key = nla_data(a);
		const struct ovs_key_ipv4 *mask = ((struct ovs_key_ipv4 *)nla_data(a) + 1); /* mask starts after key */

		if (mask->ipv4_tos) {
			ovsmgr_info("%px: Change ipv4 TOS/DSCP to %x:%d\n", key, mask->ipv4_tos, key->ipv4_tos);
			return key->ipv4_tos;
		}

		break;
	}
	case OVS_KEY_ATTR_IPV6: {
		const struct ovs_key_ipv6 *key = nla_data(a);
		const struct ovs_key_ipv6 *mask = ((struct ovs_key_ipv6*)nla_data(a) + 1); /* mask starts after key */

		if (mask->ipv6_tclass) {
			ovsmgr_info("%px: Change ipv4 TOS/DSCP to %x:%d\n",
					key, mask->ipv6_tclass,  key->ipv6_tclass);
			return key->ipv6_tclass;
		}
		break;

	}
	}

	return OVSMGR_INVALID_DSCP;
}

/*
 * ovsmgr_dp_flow_can_eth_set_accel()
 *	Validate Ethernet set actions and see if flow can be accelerated
 */
static bool ovsmgr_dp_flow_can_eth_set_accel(const struct ovs_key_ethernet *key, const struct ovs_key_ethernet *mask,
						struct sk_buff *skb)
{
	struct ethhdr *eh;
	u8 new_saddr[ETH_HLEN], new_daddr[ETH_HLEN];

	eh = eth_hdr(skb);

	ovsmgr_dp_eth_mask_addr(eh->h_source, key->eth_src, mask->eth_src, new_saddr);
	ovsmgr_dp_eth_mask_addr(eh->h_dest, key->eth_dst, mask->eth_dst, new_daddr);
	if (!ether_addr_equal(eh->h_source, new_saddr) ||
	    !ether_addr_equal(eh->h_dest, new_daddr)) {
		ovsmgr_trace("%px: Change Source/Dest MAC address SMAC: %pM->%pM, DMAC: %pM->%pM\n", key,
				eh->h_source, new_saddr, eh->h_dest, new_daddr);
		return false;
	}

	return true;
}

/*
 * ovsmgr_dp_flow_can_ipv4_set_accel()
 *	Validate IPv4 set actions and see if flow can be accelerated
 */
static bool ovsmgr_dp_flow_can_ipv4_set_accel(const struct ovs_key_ipv4 *key, const struct ovs_key_ipv4 *mask, struct sk_buff *skb)
{
	struct iphdr *iph;

	/*
	 * Check if IP header parameters are changing.
	 * Allow only DSCP remarking, if other parameters are changing then
	 * do not allow acceleration.
	 */
	iph = ip_hdr(skb);
	if (mask->ipv4_src) {
		__be32 new_addr;

		new_addr = OVS_MASKED(iph->saddr, key->ipv4_src, mask->ipv4_src);
		if (unlikely(new_addr != iph->saddr)) {
			ovsmgr_trace("%px: Source IP address is changing - %pI4->%pI4\n", key, &iph->saddr, &new_addr);
			return false;
		}
	}

	if (mask->ipv4_dst) {
		__be32 new_addr;

		new_addr = OVS_MASKED(iph->daddr, key->ipv4_dst, mask->ipv4_dst);
		if (unlikely(new_addr != iph->daddr)) {
			ovsmgr_trace("%px: Destination IP address is changing - %pI4->%pI4\n", key, &iph->daddr, &new_addr);
			return false;
		}
	}

	if (mask->ipv4_ttl) {
		u8 new_ttl;

		new_ttl = OVS_MASKED(iph->ttl, key->ipv4_ttl, mask->ipv4_ttl);
		if (unlikely(new_ttl != iph->ttl)) {
			ovsmgr_trace("%px: TTL is changing - %d->%d\n", key, iph->ttl, new_ttl);
			return false;
		}
	}

	if (mask->ipv4_tos) {
		ovsmgr_info("%px: Change ipv4 TOS/DSCP to %x:%d\n", key, mask->ipv4_tos, key->ipv4_tos);
		return true;
	}

	return false;
}

/*
 * ovsmgr_dp_flow_can_ipv6_set_accel()
 *	Validate IPv6 set actions and see if flow can be accelerated
 */
static bool ovsmgr_dp_flow_can_ipv6_set_accel(const struct ovs_key_ipv6 *key, const struct ovs_key_ipv6 *mask, struct sk_buff *skb)
{
	struct ipv6hdr *ip6h;

	/*
	 * Check if IPv6 header parameters are changing.
	 * Allow only DSCP remarking, if other parameters are changing then
	 * do not allow acceleration.
	 */
	ip6h = ipv6_hdr(skb);
	if (ovsmgr_dp_is_ipv6_mask_nonzero(mask->ipv6_src)) {
		__be32 *saddr = (__be32 *)&ip6h->saddr;
		__be32 new_addr[4];

		ovsmgr_dp_ipv6_mask_addr(saddr, key->ipv6_src, mask->ipv6_src, new_addr);
		if (unlikely(memcmp(saddr, new_addr, sizeof(new_addr)))) {
			ovsmgr_trace("%px: Source IP address is changing - %pI6->%pI6\n", key, saddr, new_addr);
			return false;
		}
	}

	if (ovsmgr_dp_is_ipv6_mask_nonzero(mask->ipv6_dst)) {
		__be32 *daddr = (__be32 *)&ip6h->daddr;
		__be32 new_addr[4];

		ovsmgr_dp_ipv6_mask_addr(daddr, key->ipv6_src, mask->ipv6_src, new_addr);
		if (unlikely(memcmp(daddr, new_addr, sizeof(new_addr)))) {
			ovsmgr_trace("%px: Destination IP address is changing - %pI6->%pI6\n", key, daddr, new_addr);
			return false;
		}
	}

	if (mask->ipv6_hlimit) {
		u8 new_hlimit;

		new_hlimit = OVS_MASKED(ip6h->hop_limit, key->ipv6_hlimit, mask->ipv6_hlimit);
		if (unlikely(new_hlimit != ip6h->hop_limit)) {
			ovsmgr_trace("%px: TTL is changing - %d->%d\n", key, ip6h->hop_limit, new_hlimit);
			return false;
		}
	}

	if (mask->ipv6_tclass) {
		ovsmgr_info("%px: Change ipv4 TOS/DSCP to %x:%d\n", key, mask->ipv6_tclass,  key->ipv6_tclass);
		return true;
	}

	return false;
}

/*
 * ovsmgr_dp_flow_can_udp_set_accel()
 *	Validate UDP set actions and see if flow can be accelerated
 */
static bool ovsmgr_dp_flow_can_udp_set_accel(const struct ovs_key_udp *key, const struct ovs_key_udp *mask, struct sk_buff *skb)
{
	struct udphdr *uh;
	__be16 src, dst;

	uh = udp_hdr(skb);
	src = OVS_MASKED(uh->source, key->udp_src, mask->udp_src);
	dst = OVS_MASKED(uh->dest, key->udp_dst, mask->udp_dst);

	if (unlikely(src != uh->source) || (unlikely(dst != uh->dest)) ) {
		ovsmgr_trace("%px: Change Source/Dest port: sport: %d->%d, dport: %d->%d\n", key,
				ntohs(uh->source), ntohs(src), ntohs(uh->dest), ntohs(dst));
		return false;
	}

	return true;
}

/*
 * ovsmgr_dp_flow_can_tcp_set_accel()
 *	Validate TCP set actions and see if flow can be accelerated
 */
static bool ovsmgr_dp_flow_can_tcp_set_accel(const struct ovs_key_tcp *key, const struct ovs_key_tcp *mask, struct sk_buff *skb)
{
	struct tcphdr *th;
	__be16 src, dst;

	th = tcp_hdr(skb);
	src = OVS_MASKED(th->source, key->tcp_src, mask->tcp_src);
	dst = OVS_MASKED(th->dest, key->tcp_dst, mask->tcp_dst);

	if (unlikely(src != th->source) || (unlikely(dst != th->dest)) ) {
		ovsmgr_trace("%px: Change Source/Dest port: sport: %d->%d, dport: %d->%d\n", key,
				ntohs(th->source), ntohs(src), ntohs(th->dest), ntohs(dst));
		return false;
	}

	return true;
}

/*
 * ovsmgr_dp_flow_can_set_mask_accel()
 *	Validate flow and actions and see if flow can be accelerated
 */
static bool ovsmgr_dp_flow_can_set_mask_accel(struct sw_flow_key *key, const struct nlattr *a, struct sk_buff *skb)
{
	switch (nla_type(a)) {
	case OVS_KEY_ATTR_PRIORITY:
	case OVS_KEY_ATTR_SKB_MARK:
		return true;
	case OVS_KEY_ATTR_IPV4: {
		    const struct ovs_key_ipv4 *v4_key = nla_data(a);
		    const struct ovs_key_ipv4 *mask = ((struct ovs_key_ipv4 *)nla_data(a) + 1); /* mask starts after key */

		    if (ovsmgr_dp_flow_can_ipv4_set_accel(v4_key, mask, skb)) {
			    ovsmgr_trace("%px: IPv4 set actions are supported\n", key);
			    return true;
		    }

		    break;
	}
	case OVS_KEY_ATTR_IPV6: {
		    const struct ovs_key_ipv6 *v6_key = nla_data(a);
		    const struct ovs_key_ipv6 *mask = ((struct ovs_key_ipv6*)nla_data(a) + 1); /* mask starts after key */

		    if (ovsmgr_dp_flow_can_ipv6_set_accel(v6_key, mask, skb)) {
			    ovsmgr_trace("%px: IPv6 set actions are supported\n", key);
			    return true;
		    }

		    break;
	}
	case OVS_KEY_ATTR_ETHERNET: {
		    const struct ovs_key_ethernet *eth_key = nla_data(a);
		    const struct ovs_key_ethernet *mask = ((struct ovs_key_ethernet*)nla_data(a) + 1); /* mask starts after key */

		    if (ovsmgr_dp_flow_can_eth_set_accel(eth_key, mask, skb)) {
			    ovsmgr_trace("%px: Ethernet set actions are supported\n", key);
			    return true;
		    }

		    break;
	}
	case OVS_KEY_ATTR_TCP: {
		    const struct ovs_key_tcp *tcp_key = nla_data(a);
		    const struct ovs_key_tcp *mask = ((struct ovs_key_tcp*)nla_data(a) + 1); /* mask starts after key */

		    if (ovsmgr_dp_flow_can_tcp_set_accel(tcp_key, mask, skb)) {
			    ovsmgr_trace("%px: TCP set actions are supported\n", key);
			    return true;
		    }

		    break;
	}
	case OVS_KEY_ATTR_UDP: {
		    const struct ovs_key_udp *udp_key = nla_data(a);
		    const struct ovs_key_udp *mask = ((struct ovs_key_udp*)nla_data(a) + 1); /* mask starts after key */

		    if (ovsmgr_dp_flow_can_udp_set_accel(udp_key, mask, skb)) {
			    ovsmgr_trace("%px: UDP set actions are supported\n", key);
			    return true;
		    }

		    break;
	}
	default:
		return false;
	}

	return false;
}

/*
 * ovsmgr_dp_flow_can_accel()
 *	Validate flow and actions and see if flow can be accelerated
 */
static bool ovsmgr_dp_flow_can_accel(struct sw_flow *sf, struct sw_flow_key *key,
					 struct sw_flow_actions *sfa, struct sk_buff *skb)
{
	struct ovsmgr_dp_port *nodp;
	struct ovsmgr_dp *nod;
	const struct nlattr *a;
	int port_num, rem;
	int egress_cnt = 0;

	/*
	 * Following are the checks done:
	 *	1. Only TCP and UDP packets are accelerated
	 *	2. Ingress port shouldn't be internal port (bridge interface)
	 *	3. Parse supported actions
	 */

	/*
	 * 1. Allow specific IP protocols
	 */
	switch (key->ip.proto) {
	case IPPROTO_TCP:
	case IPPROTO_UDP:
		break;
	default:
		ovsmgr_warn("%px: IP protocol is not supported, proto=%d\n", sf, key->ip.proto);
		return false;
	}

	/*
	 * 2. Do not allow incoming routed packets, ingress
	 *    interface shouldn't be bridge interface
	 */
	port_num = key->phy.in_port;
	read_lock(&ovsmgr_ctx.lock);

	nod = ovsmgr_dp_find_by_port(port_num);
	if (!nod) {
		read_unlock(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: datapath instance is not found, ingress port_num = %d\n", sf, port_num);
		return false;
	}

	nodp = ovsmgr_dp_port_find_by_num(nod, port_num);
	if (!nodp) {
		read_unlock(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: datapath port instance is not found, ingress port_num = %d\n", sf, port_num);
		return false;
	}

	/*
	 * Do not accelerate packets received from OVS bridge interface.
	 * These are routed flows.
	 */
	if (nodp->vport_type == OVS_VPORT_TYPE_INTERNAL) {
		read_unlock(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: ingress port(%d:%s): incoming routed flows not forwarded through hook.\n",
				sf, port_num, nodp->dev->name);
		return false;
	}
	read_unlock(&ovsmgr_ctx.lock);

	for (a = sfa->actions, rem = sfa->actions_len; rem > 0;
			a = nla_next(a, &rem)) {
		/*
		 * 3. Allow specific actions
		 *	- Allow multiple output actions (multiple egress ports) only for multicast
		 *	  flow.
		 *	- Allow specific actions, if any other action is set for
		 *	  this flow then do not accelerate.
		 */
		switch (nla_type(a)) {
		case OVS_ACTION_ATTR_OUTPUT: {

			port_num = nla_get_u32(a);

			read_lock(&ovsmgr_ctx.lock);
			nodp = ovsmgr_dp_port_find_by_num(nod, port_num);
			if (!nodp) {
				read_unlock(&ovsmgr_ctx.lock);
				ovsmgr_warn("%px: datapath port instance is not found, port_num = %d\n", sf, port_num);
				return false;
			}

			if (nodp->vport_type == OVS_VPORT_TYPE_INTERNAL) {
				read_unlock(&ovsmgr_ctx.lock);
				ovsmgr_warn("%px: output port(%d:%s): egress routed flows not forwarded through hook.\n",
						sf, port_num, nodp->dev->name);
				return false;
			}

			read_unlock(&ovsmgr_ctx.lock);
			egress_cnt++;
		}
		case OVS_ACTION_ATTR_PUSH_VLAN:
		case OVS_ACTION_ATTR_POP_VLAN:
		case OVS_ACTION_ATTR_CT:
		     break;
		case OVS_ACTION_ATTR_SET_MASKED:
		case OVS_ACTION_ATTR_SET_TO_MASKED: {
		     ovsmgr_info("%px: Action is SET_MASKED/SET_TO_MASKED: %d\n", sf, nla_type(a));
		     if (!ovsmgr_dp_flow_can_set_mask_accel(&sf->key, nla_data(a), skb)) {
			     return false;
		     }

		     break;
		}
		default:
		     ovsmgr_warn("%px: Action is not supported, action=%x\n", sf, nla_type(a));
		     return false;
		}
	}

	/*
	 * Do not accelerate the flow if egress_cnt is more than 1 and
	 * destination IP is unicast.  This could be a broadcast flow rule
	 * to find the egress for destination port.
	 */
	if ((egress_cnt > 1) && (skb->pkt_type != PACKET_MULTICAST)) {
		ovsmgr_warn("%px: Not multicast packet :egress > 1, type = %d, egress_cnt = %d\n",
				sf, skb->pkt_type, egress_cnt);
		return false;
	}

	return true;
}

/*
 * ovsmgr_dp_flow_first_egress_find()
 *	Find the first egress port from flow rule
 */
static int ovsmgr_dp_flow_first_egress_find(struct sw_flow *sf)
{
	struct sw_flow_actions *sfa;
	const struct nlattr *a;
	int rem;

	if (!sf) {
		ovsmgr_warn("flow is null\n");
		return -EINVAL;
	}

	sfa = rcu_dereference(sf->sf_acts);
	if (!sfa) {
		ovsmgr_warn("%px: flow actions is null\n", sf);
		return -EINVAL;
	}

	for (a = sfa->actions, rem = sfa->actions_len; rem > 0;
	     a = nla_next(a, &rem)) {

		if (nla_type(a) == OVS_ACTION_ATTR_OUTPUT) {
			return nla_get_u32(a);
		}
	}

	return -EINVAL;
}

/*
 * ovsmgr_dp_flow_egress_find()
 *	Return the first output interface in the actions
 */
static struct net_device *ovsmgr_dp_flow_egress_find(void *dp, struct sw_flow *sf)
{
	int port_num;

	port_num = ovsmgr_dp_flow_first_egress_find(sf);
	if (unlikely(port_num < 0)) {
		return NULL;
	}

	return ovs_accel_dev_find(dp, port_num);
}

/*
 * ovsmgr_dp_flow_get()
 *	Return the flow tuple from datapath flow rule
 */
static int ovsmgr_dp_flow_get(void *dp, struct sw_flow *sf, struct ovsmgr_dp_flow *flow)
{
	struct sw_flow_key *key = &sf->key;

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

	flow->indev = ovs_accel_dev_find(dp, key->phy.in_port);
	flow->outdev = ovsmgr_dp_flow_egress_find(dp, sf);

	ether_addr_copy(flow->smac, key->eth.src);
	ether_addr_copy(flow->dmac, key->eth.dst);

	if (key->eth.type == htons(ETH_P_IP)) {
		memcpy(&flow->tuple.ipv4, &key->ipv4.addr, sizeof(flow->tuple.ipv4));
		flow->tuple.ip_version = 4;
	} else if (key->eth.type == htons(ETH_P_IPV6)) {
		memcpy(&flow->tuple.ipv6, &key->ipv6.addr, sizeof(flow->tuple.ipv6));
		flow->tuple.ip_version = 6;
	} else {
		ovsmgr_warn("%px: Eth type is not accelerated: %x\n", sf, htons(key->eth.type));
		return -EINVAL;
	}

	/*
	 * copy ingress VLAN
	 */
	if (OVSMGR_KEY_VLAN_TCI(key)) {
		flow->ingress_vlan.h_vlan_TCI = ntohs(OVSMGR_KEY_VLAN_TCI(key)) & ~VLAN_TAG_PRESENT;
		ovsmgr_info("%px: ingress VLAN tag is %X\n", sf, flow->ingress_vlan.h_vlan_TCI);
	}

	flow->tuple.src_port = key->tp.src;
	flow->tuple.dst_port = key->tp.dst;
	flow->tuple.protocol = key->ip.proto;

	if (!flow->outdev || !flow->indev) {
		ovsmgr_warn("%px: Output device (outdev:%p) or (indev:%p) is NULL\n", sf, flow->outdev, flow->indev);
		return -EINVAL;
	}

	return 0;
}

/*
 * ovsmgr_dp_pkt_process()
 *	Process datapath packet.
 */
static void ovsmgr_dp_pkt_process(void *dp, struct sk_buff *skb, struct sw_flow_key *key,
		struct sw_flow *sf, struct sw_flow_actions *sfa)
{
	struct ovs_skb_cb ovs_cb;
	struct ovsmgr_dp_hook_ops *ops;
	struct net_device *out;
	bool hook_called = false;

	/*
	 * skb->cb is used internally by OVS datapath.
	 * Save skb->cb before using, restore it back before returning.
	 */
	ovs_cb = *OVS_CB(skb);
	atomic64_inc(&ovsmgr_ctx.stats.pkts_from_ovs_dp);

	/*
	 * Call pre-flow hook if flow is NULL
	 */
	if (!sf) {
		/*
		 * Forward only IGMP/ICMPv6 packets.
		 */
		if (likely(key->ip.proto != IPPROTO_IGMP) && likely(key->ip.proto != IPPROTO_ICMPV6))
			return;

		/*
		 * Pull Ethernet header from skb before forwarding the packet to hook
		 */
		skb_pull(skb, ETH_HLEN);
		list_for_each_entry(ops, &ovsmgr_ctx.dp_hooks, list) {
			if (ops->hook_num == OVSMGR_DP_HOOK_PRE_FLOW_PROC) {
				ops->hook(skb, NULL);
				hook_called = true;
			}
		}

		/*
		 * Restore Ethernet header
		 */
		skb_push(skb, ETH_HLEN);

		if (!hook_called) {
			ovsmgr_warn("%px: Pre flow hook is not registered.\n", dp);
		} else {
			atomic64_inc(&ovsmgr_ctx.stats.pkts_fwd_pre_flow);
		}

		return;
	}

	if (!ovsmgr_dp_flow_can_accel(sf, key, sfa, skb)) {
		ovsmgr_warn("%px: flow cannot be accelerated\n", skb);
		return;
	}

	out = ovsmgr_dp_flow_egress_find(dp, sf);
	if (unlikely(!out)) {
		ovsmgr_warn("%px: egress interface is not found in flow rule - %px\n", skb, sf);
		return;
	}

	/*
	 * Pull Ethernet header from skb before forwarding the packet to hook
	 */
	hook_called = false;
	OVSMGR_OVS_CB(skb)->flow = sf;
	OVSMGR_OVS_CB(skb)->ovs_sig = OVSMGR_SKB_SIGNATURE;

	skb_pull(skb, ETH_HLEN);
	list_for_each_entry(ops, &ovsmgr_ctx.dp_hooks, list) {
		if (ops->hook_num == OVSMGR_DP_HOOK_POST_FLOW_PROC) {
			ops->hook(skb, out);
			hook_called = true;
		}
	}

	/*
	 * Restore Ethernet header
	 */
	skb_push(skb, ETH_HLEN);

	if (!hook_called) {
		ovsmgr_warn("%px: Post flow hook is not registered.\n", dp);
	} else {
		atomic64_inc(&ovsmgr_ctx.stats.pkts_fwd_post_flow);
	}

	/*
	 * Restore skb->cb
	 */
	*OVS_CB(skb) = ovs_cb;
}

/*
 * ovsmgr_dp_port_vlan_notify()
 *	Send VLAN add/del notification
 */
static void ovsmgr_dp_port_vlan_notify(void *dp, struct ovsmgr_dp_flow *flow, int event)
{
	struct ovsmgr_dp_port_vlan_info vlan;
	struct ovsmgr_notifiers_info info;
	struct ovsmgr_dp_port *nodp;
	struct ovsmgr_dp *nod;
	int i;

	read_lock_bh(&ovsmgr_ctx.lock);

	nod = ovsmgr_dp_find(dp);
	if (!nod) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: datapath instance is not found\n", dp);
		return;
	}

	nodp = ovsmgr_dp_port_find_by_dev(nod, flow->indev);
	if (!nodp) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: Port is not found, dev = %s\n", dp, flow->indev->name);
		return;
	}

	/*
	 * Check if VLAN is set for the port.
	 */
	for (i = 0; i < OVSMGR_PORT_VLAN_MAX_CNT; i++) {
		if (nodp->vlan[i].h_vlan_TCI == flow->ingress_vlan.h_vlan_TCI) {
			if (event == OVSMGR_DP_VLAN_ADD) {
				/*
				 * VLAN ID is already notified
				 */
				read_unlock_bh(&ovsmgr_ctx.lock);
				return;
			}

			if (event == OVSMGR_DP_VLAN_DEL) {
				vlan.dev = flow->indev;
				vlan.master = nodp->master_dev;
				vlan.vh.h_vlan_TCI = flow->ingress_vlan.h_vlan_TCI;
				info.vlan = &vlan;
				ovsmgr_notifiers_call(&info, OVSMGR_DP_VLAN_DEL);
				nodp->vlan[i].h_vlan_TCI = 0;
				read_unlock_bh(&ovsmgr_ctx.lock);
				return;
			}
		}
	}

	for (i = 0; i < OVSMGR_PORT_VLAN_MAX_CNT; i++) {
		if (!nodp->vlan[i].h_vlan_TCI) {
			nodp->vlan[i].h_vlan_TCI = flow->ingress_vlan.h_vlan_TCI;
			vlan.dev = flow->indev;
			vlan.master = nodp->master_dev;
			vlan.vh.h_vlan_TCI = flow->ingress_vlan.h_vlan_TCI;
			info.vlan = &vlan;
			ovsmgr_notifiers_call(&info, OVSMGR_DP_VLAN_ADD);
			break;
		}
	}

	read_unlock_bh(&ovsmgr_ctx.lock);
}

/*
 * ovsmgr_dp_flow_tbl_flush()
 *	Flow table is flushed in datapath
 */
static void ovsmgr_dp_flow_tbl_flush(void *dp)
{
	ovsmgr_notifiers_call(NULL, OVSMGR_DP_FLOW_TBL_FLUSH);
}

/*
 * ovsmgr_dp_flow_del()
 *	Flow rule is deleted from datapath
 */
static void ovsmgr_dp_flow_del(void *dp, struct sw_flow *sf)
{
	struct ovsmgr_notifiers_info info;
	struct ovsmgr_dp_flow flow;

	ovsmgr_info("%px: flow del - %px\n", dp, sf);
	ovsmgr_dp_flow_dump(sf);

	if (!ovsmgr_dp_flow_get(dp, sf, &flow)) {
		if (flow.ingress_vlan.h_vlan_TCI) {
			ovsmgr_dp_port_vlan_notify(dp, &flow, OVSMGR_DP_VLAN_DEL);
		}

		info.flow = &flow;
		ovsmgr_notifiers_call(&info, OVSMGR_DP_FLOW_DEL);
	}
}

/*
 * ovsmgr_dp_flow_drop()
 *	Check if flow (sf) is set to drop (old actions sfa) and notify delete.
 */
static inline void ovsmgr_dp_flow_drop(void *dp, struct sw_flow *sf, struct sw_flow_actions *old_sfa, struct ovsmgr_dp_flow *flow)
{
	struct sw_flow_actions *new_acts;
	struct ovsmgr_notifiers_info info;
	const struct nlattr *a;
	int rem, port_num = -1;

	if (!old_sfa) {
		ovsmgr_info("%px: old_acts is NULL\n", dp);
		return;
	}

	new_acts = ovsl_dereference(sf->sf_acts);
	if (!new_acts) {
		ovsmgr_info("%px: new_acts is NULL\n", dp);
		return;
	}

	/*
	 * Check if flow action is set to drop in datapath
	 */
	if (new_acts->actions_len) {
		ovsmgr_info("%px: new_acts length is not 0\n", dp);
		return;
	}

	ovsmgr_trace("%px: flow drop rule is added in datapath (indev=%s, outdev=%s)\n", dp,
			flow->indev ? flow->indev->name : NULL,
			flow->outdev ? flow->outdev->name : NULL);

	/*
	 * Validate flow, it is possible that the flow may not be accelerated.
	 */
	if (!flow->tuple.ip_version) {
		ovsmgr_info("%px: flow->is not IPv6 or IPv4\n", dp);
		return;
	}

	if (unlikely(!flow->indev)) {
		ovsmgr_info("%px: flow->indev is NULL\n", dp);
		return;
	}

	for (a = old_sfa->actions, rem = old_sfa->actions_len; rem > 0;
	     a = nla_next(a, &rem)) {

		switch (nla_type(a)) {
		case OVS_ACTION_ATTR_OUTPUT:

			/*
			 * If the flow is multicast then output action can be many.
			 *  port_num will hold the last output port.
			 */
			port_num = nla_get_u32(a);

#if __has_attribute(__fallthrough__)
	__attribute__((__fallthrough__));
#endif

		case OVS_ACTION_ATTR_PUSH_VLAN:
		case OVS_ACTION_ATTR_POP_VLAN:
		case OVS_ACTION_ATTR_CT:
		case OVS_ACTION_ATTR_SET_MASKED:
		case OVS_ACTION_ATTR_SET_TO_MASKED:
			continue;

		default:
			ovsmgr_info("%px: flow was not accelerated, old action(%d)\n", dp, nla_type(a));
			return;
		}
	}

	if (port_num == -1) {
		ovsmgr_info("%px: port number could not found for old flow\n", dp);
		return;
	}

	flow->outdev = ovs_accel_dev_find(dp, port_num);
	if (!flow->outdev) {
		ovsmgr_info("%px: flow->outdev is NULL for portnum=%d\n", dp, port_num);
		return;
	}

	ovsmgr_trace("%px: Flow is set to drop packets in datapath, sending delete notify (indev=%s, outdev=%s, port=%d)\n",
					dp, flow->indev->name, flow->outdev->name, port_num);

	info.flow = flow;
	ovsmgr_notifiers_call(&info, OVSMGR_DP_FLOW_DEL);
}

/*
 * ovsmgr_dp_flow_set()
 *	Flow rule is modified
 */
static void ovsmgr_dp_flow_set(void *dp, struct sw_flow *sf, struct sw_flow_actions *sfa)
{
	struct ovsmgr_notifiers_info info;
	struct ovsmgr_dp_flow flow;

	ovsmgr_info("%px: flow set - %px:%px\n", dp, sf, sfa);
	ovsmgr_dp_flow_dump(sf);

	/*
	 * Check if old rule got modified to a "drop" rule. If so, defunct the old
	 * connection in Acceleration engine.
	 */
	if (ovsmgr_dp_flow_get(dp, sf, &flow)) {
		return ovsmgr_dp_flow_drop(dp, sf, sfa, &flow);
	}

	info.flow = &flow;
	if (is_multicast_ether_addr(flow.dmac)) {
		/*
		 * Multicast flow is updated, send change notifier.
		 */
		ovsmgr_notifiers_call(&info, OVSMGR_DP_FLOW_CHANGE);
	} else {
		/*
		 * Unicast flow is updated, send delete notifier.
		 */
		ovsmgr_notifiers_call(&info, OVSMGR_DP_FLOW_DEL);
	}
}

/*
 * ovsmgr_dp_flow_add()
 *	New flow rule is added in the datapath
 */
static void ovsmgr_dp_flow_add(void *dp, struct sw_flow *sf)
{
	struct ovsmgr_notifiers_info info;
	struct ovsmgr_dp_flow flow;

	ovsmgr_info("%px: flow add - %px\n", dp, sf);
	ovsmgr_dp_flow_dump(sf);

	if (!ovsmgr_dp_flow_get(dp, sf, &flow)) {
		if (flow.ingress_vlan.h_vlan_TCI) {
			ovsmgr_dp_port_vlan_notify(dp, &flow, OVSMGR_DP_VLAN_ADD);
		}

		info.flow = &flow;
		ovsmgr_notifiers_call(&info, OVSMGR_DP_FLOW_ADD);
	}
}

/*
 * ovsmgr_dp_port_del()
 *	OVS datapath port is deleted
 */
static void ovsmgr_dp_port_del(void *dp, void *vp, struct net_device *dev)
{
	struct ovsmgr_notifiers_info info;
	struct ovsmgr_dp_port_info port;
	struct ovsmgr_dp_port *nodp;
	struct ovsmgr_dp *nod;
	struct net_device *master_dev;
	bool is_vport_internal = false;

	ovsmgr_info("%px:%px port deleting - dev = %s\n", dp, vp, dev->name);

	write_lock_bh(&ovsmgr_ctx.lock);
	nod = ovsmgr_dp_find(dp);
	if (!nod) {
		write_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: datapath instance is not found\n", dp);
		return;
	}

	nodp = ovsmgr_dp_port_find_by_dev(nod, dev);
	if (!nodp) {
		write_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: Port is not found, dev = %s\n", dp, dev->name);
		return;
	}

	master_dev = nodp->master_dev;
	if (nodp->vport_type == OVS_VPORT_TYPE_INTERNAL) {
		is_vport_internal = true;
	}

	/*
	 * Remove port instance
	 */
	list_del(&nodp->node);
	write_unlock_bh(&ovsmgr_ctx.lock);

	kfree(nodp);

	/*
	 * Check if master_dev and dev are same and they are internal port.
	 * These conditions will mean that bridge device is deleted,
	 * send OVSMGR_DP_BR_DEL notifier.
	 */
	if ((master_dev == dev) && is_vport_internal) {
		info.dev = master_dev;
		ovsmgr_notifiers_call(&info, OVSMGR_DP_BR_DEL);
		return;
	}

	port.master = master_dev;
	port.dev = dev;
	info.port = &port;

	ovsmgr_notifiers_call(&info, OVSMGR_DP_PORT_DEL);
}

/*
 * ovsmgr_dp_port_add()
 *	New OVS datapath port is added
 */
static void ovsmgr_dp_port_add(void *dp, void *vp, int vp_num, enum ovs_vport_type vp_type,
				   const char *master, struct net_device *dev)
{
	struct ovsmgr_notifiers_info info;
	struct ovsmgr_dp_port_info port;
	struct ovsmgr_dp_port *nodp;
	struct ovsmgr_dp *nod;
	struct net_device *master_dev = NULL;

	if (!master) {
		ovsmgr_info("%px: There is no master\n", dp);
	} else {
		ovsmgr_info("%px: Master device name set: %s\n", dp, master);
		master_dev = __dev_get_by_name(&init_net, master);
		if (!master_dev) {
			ovsmgr_warn("%px: Master netdev not found\n", dp);
		}
	}

	ovsmgr_info("%px:%px new port - dev = %s\n", dp, vp, dev->name);

	nodp = kmalloc(sizeof(*nodp), GFP_KERNEL);
	if (!nodp) {
		ovsmgr_warn("%px: Memory allocation failed\n", dp);
		return;
	}

	INIT_LIST_HEAD(&nodp->node);
	nodp->dev = dev;
	nodp->master_dev = master_dev;
	nodp->vport_type = vp_type;
	nodp->vport = vp;
	nodp->vport_num = vp_num;
	nodp->add_notified = false;
	if (master) {
		strlcpy(nodp->master_name, master, IFNAMSIZ);
		ovsmgr_info("%px: Master device name set: %s\n", dp, master);
		master_dev = __dev_get_by_name(&init_net, master);
		if (!master_dev) {
			ovsmgr_warn("%px: Master netdev not found\n", dp);
		}
	}

	write_lock_bh(&ovsmgr_ctx.lock);

	nod = ovsmgr_dp_find(dp);
	if (!nod) {
		write_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: datapath instance is not found\n", dp);
		kfree(nodp);
		return;
	}

	list_add(&nodp->node, &nod->port_list);
	write_unlock_bh(&ovsmgr_ctx.lock);

	/*
	 * OVS bridge interface is also a port in datapath.  It
	 * can be created before or after bridge ports.  So it is
	 * possible that master is set but master_dev is NULL.  Generate
	 * OVSMGR_DP_PORT_ADD notifier if master_dev is set, otherwise
	 * generate when ovs bridge is created.
	 */
	if (master_dev && (vp_type != OVS_VPORT_TYPE_INTERNAL)) {
		port.master = master_dev;
		port.dev = dev;
		info.port = &port;
		ovsmgr_notifiers_call(&info, OVSMGR_DP_PORT_ADD);
		nodp->add_notified = true;
		return;
	}

	/*
	 * If master_dev is same as dev, it means that OVS bridge interface is
	 * created.  Send OVSMGR_DP_BR_ADD notifier and later send
	 * OVSMGR_DP_PORT_ADD notifier for all the ports which are created
	 * before bridge interface.
	 */
	if ((vp_type == OVS_VPORT_TYPE_INTERNAL) && (master_dev == dev)) {
		info.dev = master_dev;
		ovsmgr_notifiers_call(&info, OVSMGR_DP_BR_ADD);
		nodp->add_notified = true;
		ovsmgr_dp_send_ports_add_notifier(nod, master_dev);
	}
}

/*
 * ovsmgr_dp_del()
 *	OVS datapath is deleted
 */
static void ovsmgr_dp_del(void *dp, struct net_device *dev)
{
	struct ovsmgr_notifiers_info info;
	struct ovsmgr_dp *nod;

	ovsmgr_info("%px: datapath deleting - dev = %s\n", dp, dev->name);

	write_lock_bh(&ovsmgr_ctx.lock);
	nod = ovsmgr_dp_find(dp);
	if (!nod) {
		write_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: datapath instance is not found\n", dp);
		return;
	}

	list_del(&nod->node);
	write_unlock_bh(&ovsmgr_ctx.lock);

	kfree(nod);
	info.dev = dev;
	ovsmgr_notifiers_call(&info, OVSMGR_DP_DEL);
}

/*
 * ovsmgr_dp_add()
 *	New OVS data path is created
 */
static void ovsmgr_dp_add(void *dp, struct net_device *dev)
{
	struct ovsmgr_notifiers_info info;
	struct ovsmgr_dp *new_dp;

	ovsmgr_info("%px: new datapath - dev = %s\n", dp, dev->name);

	new_dp = kmalloc(sizeof(*new_dp), GFP_KERNEL);
	if (!new_dp) {
		ovsmgr_warn("%px: failed to allocation memory\n", dp);
		return;
	}

	INIT_LIST_HEAD(&new_dp->node);
	INIT_LIST_HEAD(&new_dp->port_list);
	new_dp->dev = dev;
	new_dp->dp = dp;

	write_lock_bh(&ovsmgr_ctx.lock);
	list_add(&new_dp->node, &ovsmgr_ctx.dp_list);
	write_unlock_bh(&ovsmgr_ctx.lock);

	info.dev = dev;
	ovsmgr_notifiers_call(&info, OVSMGR_DP_ADD);
}

/*
 * OVS datapath acceleration callbacks
 */
static struct ovs_accel_callback ovs_cb = {
	.ovs_accel_dp_add = ovsmgr_dp_add,
	.ovs_accel_dp_del = ovsmgr_dp_del,
	.ovs_accel_dp_port_add = ovsmgr_dp_port_add,
	.ovs_accel_dp_port_del = ovsmgr_dp_port_del,
	.ovs_accel_dp_flow_add = ovsmgr_dp_flow_add,
	.ovs_accel_dp_flow_del = ovsmgr_dp_flow_del,
	.ovs_accel_dp_flow_set = ovsmgr_dp_flow_set,
	.ovs_accel_dp_flow_tbl_flush = ovsmgr_dp_flow_tbl_flush,
	.ovs_accel_dp_pkt_process = ovsmgr_dp_pkt_process
};

/*
 * ovsmgr_dp_flow_key_fill()
 *	Fill key from flow and in_port
 */
static void ovsmgr_dp_flow_key_fill(struct ovsmgr_dp_flow *flow, int in_port, struct sw_flow_key *key)
{
	memset(key, 0, sizeof(*key));

	key->phy.in_port = in_port;
	ether_addr_copy(key->eth.src, flow->smac);
	ether_addr_copy(key->eth.dst, flow->dmac);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
	key->mac_proto = MAC_PROTO_ETHERNET;
#endif

	if (flow->ingress_vlan.h_vlan_TCI) {
		OVSMGR_KEY_VLAN_TCI(key) = htons(flow->ingress_vlan.h_vlan_TCI | VLAN_TAG_PRESENT);
	}

	if (flow->tuple.ip_version == 4) {
		key->ipv4.addr.src = flow->tuple.ipv4.src;
		key->ipv4.addr.dst = flow->tuple.ipv4.dst;
		key->eth.type = htons(ETH_P_IP);
	} else {
		memcpy(&key->ipv6.addr.src, &flow->tuple.ipv6.src, sizeof(key->ipv6.addr.src));
		memcpy(&key->ipv6.addr.dst, &flow->tuple.ipv6.dst, sizeof(key->ipv6.addr.dst));
		key->eth.type = htons(ETH_P_IPV6);
	}

	key->tp.src = flow->tuple.src_port;
	key->tp.dst = flow->tuple.dst_port;
	key->ip.proto = flow->tuple.protocol;

	ovsmgr_dp_flow_key_dump(key);
}

/*
 * ovsmgr_dp_flow_info_get_by_mac()
 *	Find OVS flow rule from MAC address and update VLAN information
 */
enum ovsmgr_flow_status ovsmgr_dp_flow_info_get_by_mac(void *dp, struct net_device *indev, struct net_device *outdev,
							u8 *src, u8 *dst, __be16 type, struct ovsmgr_flow_info *ofi)
{
	struct sw_flow_key *sfk;
	struct sw_flow *sf;

	sf = ovs_accel_flow_find_by_mac(dp, indev, outdev, src, dst, type);
	if (!sf) {
		ovsmgr_warn("%px: Couldn't find flow rule using indev:%s, outdev:%s, SMAC:%pM, DMAC:%pM type:0x%x\n",
				dp, indev ? indev->name:"NULL", outdev ? outdev->name:"NULL", src, dst, type);
		return OVSMGR_FLOW_STATUS_DENY_ACCEL;
	}

	/*
	 * Flow is found and flow key has ingress packet details.
	 * If the flow rule is expecting VLAN header then it is expected
	 * that from indev packet should be transmitted with VLAN header.
	 * Copy ingress VLAN header to egress VLAN in VLAN info.
	 */
	sfk = &sf->key;
	if (OVSMGR_KEY_VLAN_TCI(sfk)) {
		ofi->egress[0].h_vlan_TCI = ntohs(OVSMGR_KEY_VLAN_TCI(sfk)) & ~VLAN_TAG_PRESENT;
		ofi->egress[0].h_vlan_encapsulated_proto = ETH_P_8021Q;
		ovsmgr_info("Egress VLAN : id = %x:%x\n",
				ofi->egress[0].h_vlan_encapsulated_proto,
				ofi->egress[0].h_vlan_TCI);
		return OVSMGR_FLOW_STATUS_ALLOW_VLAN_ACCEL;
	}

	return OVSMGR_FLOW_STATUS_ALLOW_ACCEL;
}

/*
 * ovsmgr_dp_flow_info_get()
 *	Fill key from flow and in_port
 */
enum ovsmgr_flow_status ovsmgr_dp_flow_info_get(struct ovsmgr_dp_flow *flow,
						     struct sk_buff *skb, struct ovsmgr_flow_info *ofi)
{
	struct ovsmgr_dp_port *in_port, *out_port;
	struct sw_flow_actions *acts;
	struct sw_flow_key key;
	struct ovsmgr_dp *nod;
	const struct nlattr *a;
	struct sw_flow *sf;
	enum ovsmgr_flow_status status = OVSMGR_FLOW_STATUS_DENY_ACCEL;
	bool found_egress = false;
	int in_port_num, out_port_num;
	int vlan_index = 0;
	int rem;
	uint64_t prev_action = OVS_ACTION_ATTR_UNSPEC;
	bool pop_vlan = false;

	read_lock_bh(&ovsmgr_ctx.lock);

	nod = ovsmgr_dp_find_by_dev(flow->indev);
	if (unlikely(!nod)) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: Couldn't find datapath instance for dev = %s\n", flow, flow->indev->name);
		return OVSMGR_FLOW_STATUS_DENY_ACCEL;
	}

	in_port = ovsmgr_dp_port_find_by_dev(nod, flow->indev);
	if (!in_port) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: input datapath port instance is not found for dev = %s\n",
				nod, flow->indev->name);
		return OVSMGR_FLOW_STATUS_DENY_ACCEL;
	}

	out_port = ovsmgr_dp_port_find_by_dev(nod, flow->outdev);
	if (!out_port) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: output datapath port instance is not found for dev = %s\n",
				nod, flow->outdev->name);
		return OVSMGR_FLOW_STATUS_DENY_ACCEL;
	}

	in_port_num = in_port->vport_num;
	out_port_num = out_port->vport_num;
	read_unlock_bh(&ovsmgr_ctx.lock);

	ovsmgr_dp_flow_key_fill(flow, in_port_num, &key);

	/*
	 * If ingress packet is VLAN tagged then copy VLAN ID
	 */
	if (flow->ingress_vlan.h_vlan_TCI) {
		/*
		 * If ingress vlan is set then there is no need to update
		 * ofi->ingress, caller is already aware that there is
		 * ingress VLAN header.
		 * This case is valid for multicast flow when there is an
		 * egress list update.
		 * Fill TCI in key, OVS datapath expects VLAN_TAG_PRESENT
		 * to be set in TCI.
		 */
		OVSMGR_KEY_VLAN_TCI(&key) = htons(flow->ingress_vlan.h_vlan_TCI) | VLAN_TAG_PRESENT;
	} else if (skb && skb_vlan_tag_present(skb)) {
		/*
		 * Read VLAN tag from skb
		 * VLAN_TAG_PRESENT is set by kernel in skb, fill TCI in key.
		 */
		OVSMGR_KEY_VLAN_TCI(&key) = htons(skb->vlan_tci);

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0))
		key.eth.vlan.tpid = htons(ETH_P_8021Q);
		OVSMGR_KEY_VLAN_TCI(&key) |= htons(VLAN_TAG_PRESENT);
#endif

		ofi->ingress[0].h_vlan_TCI = skb_vlan_tag_get(skb);
		ofi->ingress[0].h_vlan_encapsulated_proto = ntohs(skb->vlan_proto);
		ovsmgr_info("Ingress VLAN : id = %x:%x\n",
				ofi->ingress[0].h_vlan_encapsulated_proto,
				ofi->ingress[0].h_vlan_TCI);

		status = OVSMGR_FLOW_STATUS_ALLOW_VLAN_ACCEL;
	}

	/*
	 * Find datapath rule with key.
	 * If rule is not found and it is a routed flow, then find rule using
	 * MAC addresses. For routed flows flow->indev is always OVS bridge interface.
	 *
	 * DSCP remarking action may not be configured.
	 * Initialize DSCP value to invalid.
	 */
	ofi->dscp = OVSMGR_INVALID_DSCP;

	sf = ovs_accel_flow_find(nod->dp, &key);
	if (!sf) {
		if (!flow->is_routed) {
			ovsmgr_warn("%px:Couldn't find flow rule \n", flow);
			return OVSMGR_FLOW_STATUS_DENY_ACCEL;
		}

		/*
		 * Multicast flows are always uni-directional, call
		 * ovsmgr_dp_flow_info_get_by_mac() API with populated
		 * source and destination mac address.
		 */
		if (is_multicast_ether_addr(flow->dmac)) {
			return ovsmgr_dp_flow_info_get_by_mac(nod->dp, flow->indev, flow->outdev,
					key.eth.src, key.eth.dst, key.eth.type, ofi);
		}

		/*
		 * For unicast flows, we need to swap the source and dest mac address
		 * as we are querying for the reverse direction.
		 */
		return ovsmgr_dp_flow_info_get_by_mac(nod->dp, flow->outdev, flow->indev, key.eth.dst,
					key.eth.src, key.eth.type, ofi);
	}

	/*
	 * Flow is found, find if VLAN operations are needed and check
	 * if egress port is allowed.
	 */
	rcu_read_lock();
	acts = rcu_dereference(sf->sf_acts);

	for (a = acts->actions, rem = acts->actions_len; rem > 0;
	     a = nla_next(a, &rem)) {
		switch (nla_type(a)) {
		case OVS_ACTION_ATTR_OUTPUT:
			if (out_port_num == nla_get_u32(a)) {
				ovsmgr_info("%px: Found egress port in flow rule: %d\n", flow, out_port_num);
				found_egress = true;
				if (status == OVSMGR_FLOW_STATUS_DENY_ACCEL)
					status = OVSMGR_FLOW_STATUS_ALLOW_ACCEL;
				break;
			}

			prev_action = OVS_ACTION_ATTR_OUTPUT;
			break;
		case OVS_ACTION_ATTR_PUSH_VLAN: {
			const struct ovs_action_push_vlan *vlan;

			vlan = nla_data(a);
			ovsmgr_info("Vlan details:\n");
			ovsmgr_info("\tvlan_tpid = %x\n", vlan->vlan_tpid);
			ovsmgr_info("\tvlan_tci = %x\n", vlan->vlan_tci & ~VLAN_TAG_PRESENT);

			/*
			 * Retain the VLAN information only for the below conditions,
			 * 1. PUSH_VLAN is the first action
			 * 2. Previous action was PUSH_VLAN
			 *
			 * Reset the VLAN information for all the other conditions.
			 */
			if ((prev_action != OVS_ACTION_ATTR_UNSPEC) &&
					(prev_action != OVS_ACTION_ATTR_PUSH_VLAN)) {
				vlan_index = 0;
				ofi->egress[0].h_vlan_TCI = 0;
				ofi->egress[0].h_vlan_encapsulated_proto = 0;
				ofi->egress[1].h_vlan_TCI = 0;
				ofi->egress[1].h_vlan_encapsulated_proto = 0;
			}

			/*
			 * Allow only two VLAN headers
			 */
			if (vlan_index == 2) {
				ovsmgr_info("%px: More than 2 VLAN headers, don't accelerate\n", flow);
				rcu_read_unlock();
				return OVSMGR_FLOW_STATUS_DENY_ACCEL;
			}

			ofi->egress[vlan_index].h_vlan_TCI = ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT;
			ofi->egress[vlan_index].h_vlan_encapsulated_proto = ntohs(vlan->vlan_tpid);
			vlan_index++;
			prev_action = OVS_ACTION_ATTR_PUSH_VLAN;
			break;
		}
		case OVS_ACTION_ATTR_POP_VLAN:
			pop_vlan = true;
			prev_action = OVS_ACTION_ATTR_POP_VLAN;
			break;
		case OVS_ACTION_ATTR_SET_MASKED:
			prev_action = OVS_ACTION_ATTR_SET_MASKED;
			ofi->dscp = ovsmgr_dp_action_set_mask_get_dscp(&sf->key, nla_data(a));
			ovsmgr_info("%px: DSCP = %x\n", sf, ofi->dscp);
			break;
		case OVS_ACTION_ATTR_SET_TO_MASKED: {
			prev_action = OVS_ACTION_ATTR_SET_TO_MASKED;
			ofi->dscp = ovsmgr_dp_action_set_mask_get_dscp(&sf->key, nla_data(a));
			ovsmgr_info("%px: DSCP = %x\n", sf, ofi->dscp);
			break;
		}
		}

		/*
		 * If the egress port is found then the job is done.
		 */
		if (found_egress) {
			break;
		}
	}
	rcu_read_unlock();

	/*
	 * Do not accelerate if flow->outdev is not part of output list
	 */
	if (!found_egress) {
		return OVSMGR_FLOW_STATUS_DENY_ACCEL;
	}

	switch (vlan_index) {
	case 1: /* return single VLAN operation. */
		return OVSMGR_FLOW_STATUS_ALLOW_VLAN_ACCEL;
	case 2: /* return QinQ VLAN operation. */
		return OVSMGR_FLOW_STATUS_ALLOW_VLAN_QINQ_ACCEL;
	}

	/*
	 * If there is no POP_VLAN action and
	 * it is a bridge flow, then the egress and ingress
	 * VLANs are same.
	 */
	if (!pop_vlan && !flow->is_routed) {
		ofi->egress[0].h_vlan_TCI = ofi->ingress[0].h_vlan_TCI;
		ofi->egress[0].h_vlan_encapsulated_proto = ofi->ingress[0].h_vlan_encapsulated_proto;
	}

	return status;
}

/*
 * ovsmgr_dp_dev_get_master()
 *	Find datapath bridge interface for given bridge port
 */
struct net_device *ovsmgr_dp_dev_get_master(struct net_device *dev)
{
	struct ovsmgr_dp *nod;
	struct ovsmgr_dp_port *nodp;
	struct net_device *master_dev;

	read_lock_bh(&ovsmgr_ctx.lock);
	nod = ovsmgr_dp_find_by_dev(dev);
	if (!nod) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("Couldn't find datapath instance, dev = %s\n", dev->name);
		return NULL;
	}

	nodp = ovsmgr_dp_port_find_by_dev(nod, dev);
	if (!nodp) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: input datapath port instance is not found for dev = %s\n",
				nod, dev->name);
		return NULL;
	}

	master_dev = nodp->master_dev;
	read_unlock_bh(&ovsmgr_ctx.lock);
	return master_dev;
}

/*
 * ovsmgr_dp_dev_is_master()
 *	Return true if dev is OVS bridge interface
 */
bool ovsmgr_dp_dev_is_master(struct net_device *dev)
{
	struct ovsmgr_dp *nod;
	struct ovsmgr_dp_port *nodp;
	bool is_master = false;

	read_lock_bh(&ovsmgr_ctx.lock);
	nod = ovsmgr_dp_find_by_dev(dev);
	if (!nod) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("Couldn't find datapath instance, dev = %s\n", dev->name);
		return false;
	}

	nodp = ovsmgr_dp_port_find_by_dev(nod, dev);
	if (!nodp) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: input datapath port instance is not found for dev = %s\n",
				nod, dev->name);
		return false;
	}

	if ((nodp->vport_type == OVS_VPORT_TYPE_INTERNAL) && (nodp->master_dev == dev)) {
		is_master = true;
	}

	read_unlock_bh(&ovsmgr_ctx.lock);
	return is_master;
}

/*
 * ovsmgr_dp_bridge_interface_stats_update()
 *	Update OVS datapath bridge interface statistics.
 */
void ovsmgr_dp_bridge_interface_stats_update(struct net_device *dev,
					  uint32_t rx_packets, uint32_t rx_bytes,
					  uint32_t tx_packets, uint32_t tx_bytes)
{
	struct pcpu_sw_netstats *ovs_stats;

	if (!ovsmgr_dp_dev_is_master(dev)) {
		ovsmgr_warn("%px: %s is not an OVS bridge device\n", dev, dev->name);
		return;
	}

	ovs_stats = this_cpu_ptr(dev->tstats);
	u64_stats_update_begin(&ovs_stats->syncp);
	ovs_stats->rx_packets += rx_packets;
	ovs_stats->rx_bytes += rx_bytes;
	ovs_stats->tx_packets += tx_packets;
	ovs_stats->tx_bytes += tx_bytes;
	u64_stats_update_end(&ovs_stats->syncp);
}

/*
 * ovsmgr_dp_flow_stats_update()
 *	Update datapath flow statistics
 */
void ovsmgr_dp_flow_stats_update(struct ovsmgr_dp_flow *flow, struct ovsmgr_dp_flow_stats *stats)
{
	struct sw_flow_key key;
	struct ovsmgr_dp_port *in_port, *out_port;
	struct ovsmgr_dp *nod;
	void *out_vport;
	int in_port_num;

	/*
	 * for bridge flows:
	 *	indev and outdev are OVS bridge ports.
	 * for route flows:
	 *	indev or outdev is OVS bridge port.
	 * TODO: Do we need to add route/bridge flag in flow?  This would
	 * help us to check if we need to find dp with outdev if indev fails
	 */
	read_lock_bh(&ovsmgr_ctx.lock);
	nod = ovsmgr_dp_find_by_dev(flow->indev);
	if (unlikely(!nod)) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: Couldn't find datapath instance for dev = %s\n", flow, flow->indev->name);
		return;
	}

	in_port = ovsmgr_dp_port_find_by_dev(nod, flow->indev);
	if (!in_port) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: input datapath port instance is not found for dev = %s\n",
				nod, flow->indev->name);
		return;
	}

	out_port = ovsmgr_dp_port_find_by_dev(nod, flow->outdev);
	if (!out_port) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: output datapath port instance is not found for dev = %s\n",
				nod, flow->outdev->name);
		return;
	}

	in_port_num = in_port->vport_num;
	out_vport = out_port->vport;
	read_unlock_bh(&ovsmgr_ctx.lock);

	ovsmgr_dp_flow_key_fill(flow, in_port_num, &key);
	if (ovs_accel_flow_stats_update(nod->dp, out_vport, &key, stats->pkts, stats->bytes)) {
		ovsmgr_warn("%px: Couldnt update statistics\n", nod->dp);
	}
}

/*
 * ovsmgr_dp_port_dev_find_by_mac()
 *	Find egress datapath port, given skb, datapath interface (dev) and flow
 */
struct net_device *ovsmgr_dp_port_dev_find_by_mac(struct sk_buff *skb, struct net_device *dev,
							struct ovsmgr_dp_flow *flow)
{
	struct ovsmgr_dp *nod;
	struct ovsmgr_dp_port *nodp;
	struct sw_flow *sf;
	struct net_device *ovs_port;
	void *dp;
	uint16_t type;

	read_lock_bh(&ovsmgr_ctx.lock);
	nod = ovsmgr_dp_find_by_dev(dev);
	if (!nod) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: Couldn't find datapath instance, dev = %s\n", skb, dev->name);
		return NULL;
	}

	nodp = ovsmgr_dp_port_find_by_dev(nod, dev);
	if (!nodp) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: Couldn't find datapath port instance, dev = %s\n", skb, dev->name);
		return NULL;
	}

	if (nodp->vport_type != OVS_VPORT_TYPE_INTERNAL) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: Interface type is not internal, dev = %s\n", skb, dev->name);
		return NULL;
	}

	dp = nod->dp;
	read_unlock_bh(&ovsmgr_ctx.lock);

	if (flow->tuple.ip_version == 4) {
		type = htons(ETH_P_IP);
	} else {
		type = htons(ETH_P_IPV6);
	}

	sf = ovs_accel_flow_find_by_mac(dp, NULL, dev, flow->smac, flow->dmac, type);
	if (!sf) {
		ovsmgr_warn("%px: datapath flow is not found with SMAC: %pM, DMAC: %pM, dev = %s\n",
				skb, flow->smac, flow->dmac, dev->name);
		return NULL;
	}

	/*
	 * Find the dev by ingress port number
	 */
	read_lock_bh(&ovsmgr_ctx.lock);
	nodp = ovsmgr_dp_port_find_by_num(nod, sf->key.phy.in_port);
	if (!nodp) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: DP port is not found, port number: %d, dev = %s\n", skb, sf->key.phy.in_port, dev->name);
		return NULL;
	}

	ovs_port = nodp->dev;
	read_unlock_bh(&ovsmgr_ctx.lock);

	return ovs_port;
}

/*
 * ovsmgr_dp_port_dev_find()
 *	Find egress datapath port, given skb and datapath interface (dev)
 */
struct net_device *ovsmgr_dp_port_dev_find(struct sk_buff *skb,
					       struct net_device *dev, struct ovsmgr_dp_flow *flow)
{
	struct ovsmgr_dp *nod;
	struct ovsmgr_dp_port *nodp;
	struct sw_flow_key key;
	void *dp;
	int vport_num;

	read_lock_bh(&ovsmgr_ctx.lock);
	nod = ovsmgr_dp_find_by_dev(dev);
	if (!nod) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: Couldn't find datapath instance, dev = %s\n", skb, dev->name);
		return NULL;
	}

	nodp = ovsmgr_dp_port_find_by_dev(nod, dev);
	if (!nodp) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: Couldn't find datapath port instance, dev = %s\n", skb, dev->name);
		return NULL;
	}

	if (nodp->vport_type != OVS_VPORT_TYPE_INTERNAL) {
		read_unlock_bh(&ovsmgr_ctx.lock);
		ovsmgr_warn("%px: Interface type is not internal, dev = %s\n", skb, dev->name);
		return NULL;
	}

	dp = nod->dp;
	vport_num = nodp->vport_num;
	read_unlock_bh(&ovsmgr_ctx.lock);

	/*
	 * Multicast address requires finding the ingress interface through all
	 * bridge ports
	 */
	if (is_multicast_ether_addr(flow->dmac)) {
		return ovsmgr_dp_mcast_port_dev_find(nod, nodp, flow, skb);
	}

	ether_addr_copy(flow->smac, dev->dev_addr);
	ovsmgr_dp_flow_key_fill(flow, vport_num, &key);

	return ovs_accel_egress_dev_find(dp, &key, skb);
}

/*
 * ovsmgr_exit()
 *	Cleanup datapath context
 */
void ovsmgr_dp_exit(void)
{
	struct ovsmgr_dp *nod, *temp_dp;

	ovs_unregister_accelerator(&ovs_cb);
	/*
	 * Cleanup the database.
	 */
	write_lock_bh(&ovsmgr_ctx.lock);
	list_for_each_entry_safe(nod, temp_dp, &ovsmgr_ctx.dp_list, node) {
		struct ovsmgr_dp_port *nodp, *temp_port;

		list_for_each_entry_safe(nodp, temp_port, &nod->port_list, node) {
			list_del(&nodp->node);
			kfree(nodp);
		}

		list_del(&nod->node);
		kfree(nod);
	}

	write_unlock_bh(&ovsmgr_ctx.lock);
}

/*
 * ovsmgr_init()
 *	Initialize datapath context
 */
int ovsmgr_dp_init(void)
{
	return ovs_register_accelerator(&ovs_cb);
}
