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

/*
 * nss_bridge_mgr_ovs.c
 *	Handle OVS bridge notifications.
 */
#include <linux/netdevice.h>
#include <linux/notifier.h>
#include <ovsmgr.h>
#include <nss_vlan_mgr.h>

#include "nss_bridge_mgr_priv.h"

/*
 * nss_bridge_mgr_ovs_handle_port_event()
 *	Handle OVS bridge port events
 */
static int nss_bridge_mgr_ovs_handle_port_event(struct ovsmgr_notifiers_info *ovs_info, unsigned long event)
{
	struct ovsmgr_dp_port_info *port;
	struct nss_bridge_pvt *b_pvt;
	struct net_device *master_dev, *dev;
	int err;

	port = ovs_info->port;
	if (!port || !port->master || !port->dev) {
		nss_bridge_mgr_warn("%px: Invalid ovs_info\n", ovs_info);
		return -EINVAL;
	}

	master_dev = port->master;
	dev = port->dev;

	/*
	 * Check if upper_dev is a known bridge.
	 */
	b_pvt = nss_bridge_mgr_find_instance(master_dev);
	if (!b_pvt) {
		nss_bridge_mgr_warn("%px: Couldn't find bridge instance for master: %s\n", port, master_dev->name);
		return -ENOENT;
	}

	/*
	 * add port to the bridge.
	 */
	if (event == OVSMGR_DP_PORT_ADD) {
		nss_bridge_mgr_trace("%px: Interface %s joining bridge %s\n", b_pvt, dev->name, master_dev->name);

		err = nss_bridge_mgr_join_bridge(dev, b_pvt);
		if (err) {
			nss_bridge_mgr_warn("%px: Interface %s failed to join bridge %s\n", b_pvt, dev->name, master_dev->name);
			return err;
		}

		return 0;
	}

	/*
	 * delete port from bridge.
	 */
	nss_bridge_mgr_trace("%px: Interface %s leaving bridge %s\n", b_pvt, dev->name, master_dev->name);

	err = nss_bridge_mgr_leave_bridge(dev, b_pvt);
	if (err) {
		nss_bridge_mgr_warn("%px: Interface %s failed to leave bridge %s\n", b_pvt, dev->name, master_dev->name);
		return err;
	}

	return 0;
}

/*
 * nss_bridge_mgr_ovs_handle_vlan_event()
 *	Handle VLAN events OVS bridge port
 */
static void nss_bridge_mgr_ovs_handle_vlan_event(struct ovsmgr_notifiers_info *ovs_info, unsigned long event)
{
	struct ovsmgr_dp_port_vlan_info *vlan;
	struct nss_bridge_pvt *b_pvt;
	struct net_device *master_dev, *dev;

	vlan = ovs_info->vlan;
	if (!vlan || !vlan->master || !vlan->dev) {
		nss_bridge_mgr_warn("%px: Invalid ovs_info\n", ovs_info);
		return;
	}

	master_dev = vlan->master;
	dev = vlan->dev;

	/*
	 * Check if upper_dev is a known bridge.
	 */
	b_pvt = nss_bridge_mgr_find_instance(master_dev);
	if (!b_pvt) {
		nss_bridge_mgr_warn("%px: Couldn't find bridge instance for master: %s\n", vlan, master_dev->name);
		return;
	}

	if (event == OVSMGR_DP_VLAN_ADD) {
		/*
		 * add VLAN in bridge.
		 */
		nss_bridge_mgr_trace("%px: VLAN = %d, add on port %s, bridge %s\n",
				b_pvt, vlan->vh.h_vlan_TCI, dev->name, master_dev->name);

		nss_vlan_mgr_add_vlan_rule(dev, b_pvt->vsi, vlan->vh.h_vlan_TCI);
		return;
	}

	/*
	 * delete VLAN from bridge.
	 */
	nss_bridge_mgr_trace("%px: VLAN = %d, delete on port %s, bridge %s\n",
					b_pvt, vlan->vh.h_vlan_TCI, dev->name, master_dev->name);
	nss_vlan_mgr_del_vlan_rule(dev, b_pvt->vsi, vlan->vh.h_vlan_TCI);
}

/*
 * nss_bridge_mgr_ovs_notifier_callback()
 *	Netdevice notifier callback to inform us of change of state of a netdevice
 */
static int nss_bridge_mgr_ovs_notifier_callback(struct notifier_block *nb, unsigned long event, void *data)
{
	struct ovsmgr_notifiers_info *ovs_info = (struct ovsmgr_notifiers_info *)data;

	nss_bridge_mgr_info("OVS notifier event: %lu\n", event);

	switch (event) {
	case OVSMGR_DP_BR_ADD:
		nss_bridge_mgr_register_br(ovs_info->dev);
		break;
	case OVSMGR_DP_BR_DEL:
		nss_bridge_mgr_unregister_br(ovs_info->dev);
		break;
	case OVSMGR_DP_PORT_ADD:
	case OVSMGR_DP_PORT_DEL:
		nss_bridge_mgr_ovs_handle_port_event(ovs_info, event);
		break;
	case OVSMGR_DP_VLAN_ADD:
	case OVSMGR_DP_VLAN_DEL:
		nss_bridge_mgr_ovs_handle_vlan_event(ovs_info, event);
		break;
	}

	return NOTIFY_DONE;
}

/*
 * struct notifier_block nss_bridge_mgr_ovs_notifier
 *	Registration for OVS events
 */
static struct notifier_block ovs_notifier __read_mostly = {
	.notifier_call = nss_bridge_mgr_ovs_notifier_callback,
};

/*
 * nss_bridge_mgr_is_ovs_port()
 *	Return true if dev is an OVS port.
 */
int nss_bridge_mgr_is_ovs_port(struct net_device *dev)
{
	if (dev->priv_flags & IFF_OVS_DATAPATH) {
		return true;
	}

	return false;
}

/*
 * nss_bridge_mgr_ovs_exit()
 *	Cleanup OVS bridge handlers.
 */
void nss_bridge_mgr_ovs_exit(void)
{
	ovsmgr_notifier_unregister(&ovs_notifier);
}

/*
 * nss_bridge_mgr_exit_module()
 *	Initialize OVS bridge handlers.
 */
void nss_bridge_mgr_ovs_init(void)
{
	ovsmgr_notifier_register(&ovs_notifier);
}
