/*
 *
 *  Copyright (C) 2007 Mindspeed Technologies, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "cmm.h"
#include "itf.h"
#include "fpp.h"
#include "cmmd.h"

#include <net/if.h>
#include <linux/if_vlan.h>
#include <linux/sockios.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>


void __cmmGetVlan(int fd, struct interface *itf)
{
	struct vlan_ioctl_args if_request;

	itf->itf_flags &= ~ITF_VLAN;

	if (itf->phys_ifindex == itf->ifindex)
		goto out;

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

	if_request.cmd = GET_VLAN_VID_CMD;
	if (____itf_get_name(itf, if_request.device1, sizeof(if_request.device1)) < 0)
	{
		cmm_print(DEBUG_ERROR, "%s: ____itf_get_name(%d) failed\n", __func__, itf->ifindex);
		goto out;
	}

	if (ioctl(fd, SIOCGIFVLAN, &if_request) < 0)
		goto out;

	itf->itf_flags |= ITF_VLAN;
	itf->vlan_id = if_request.u.VID;

out:
	return;
}
/*****************************************************************
* cmmFeVLANUpdate
*
*
******************************************************************/
int cmmFeVLANUpdate(FCI_CLIENT *fci_handle, int request, struct interface *itf)
{
	fpp_vlan_cmd_t cmd;
	short ret = CMMD_ERR_OK;
	int action;

	switch (request)
	{
	default:
	case ADD:
		if ((itf->flags & (FPP_PROGRAMMED | FPP_NEEDS_UPDATE)) == FPP_PROGRAMMED)
			goto out;

		if ((itf->flags & (FPP_PROGRAMMED | FPP_NEEDS_UPDATE)) == (FPP_PROGRAMMED | FPP_NEEDS_UPDATE))
		{
			cmm_print(DEBUG_ERROR, "%s: trying to update vlan interface(%d)\n", __func__, itf->ifindex);
			ret = CMMD_ERR_NOT_CONFIGURED;
			goto out;
		}

		action = FPP_ACTION_REGISTER;

		break;

	case REMOVE:
		if (!(itf->flags & FPP_PROGRAMMED))
			goto out;

		action = FPP_ACTION_DEREGISTER;

		break;
	}

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

	cmd.action = action;

	if (____itf_get_name(itf, cmd.vlan_ifname, sizeof(cmd.vlan_ifname)) < 0)
	{
		cmm_print(DEBUG_ERROR, "%s: ____itf_get_name(%d) failed\n", __func__, itf->ifindex);
		ret = CMMD_ERR_WRONG_COMMAND_PARAM;
		goto out;
	}

	cmd.vlan_id = itf->vlan_id;

	switch (action)
	{
	case FPP_ACTION_REGISTER:
		cmm_print(DEBUG_COMMAND, "Send CMD_VLAN_ENTRY ACTION_REGISTER\n");

		if (__itf_get_name(itf->phys_ifindex, cmd.vlan_phy_ifname, sizeof(cmd.vlan_phy_ifname)) < 0)
		{
			cmm_print(DEBUG_ERROR, "%s: __itf_get_name(%d) failed\n", __func__, itf->phys_ifindex);
			ret = CMMD_ERR_WRONG_COMMAND_PARAM;
			goto out;
		}

		ret = fci_write(fci_handle, FPP_CMD_VLAN_ENTRY, sizeof(fpp_vlan_cmd_t), (unsigned short *) &cmd);
		if ((ret == FPP_ERR_OK) || (ret == FPP_ERR_VLAN_ENTRY_ALREADY_REGISTERED))
		{
			itf->flags |= FPP_PROGRAMMED;
			itf->flags &= ~FPP_NEEDS_UPDATE;
		}
		else
		{
			cmm_print(DEBUG_ERROR, "%s: Error %d while sending CMD_VLAN_ENTRY, ACTION_REGISTER\n", __func__, ret);
			goto out;
		}

		break;
#if 0
	case ACTION_UPDATE:
		cmm_print(DEBUG_COMMAND, "Send CMD_VLAN_ENTRY ACTION_UPDATE\n");

		ret = fci_write(fci_handle, CMD_VLAN_ENTRY, sizeof(struct VlanCmd), (unsigned short *) &cmd);
		if (ret == NO_ERR)
		{
			itf->flags &= ~FPP_NEEDS_UPDATE;
		}
		else
		{
			cmm_print(DEBUG_ERROR, "%s: Error %d while sending CMD_VLAN_ENTRY, ACTION_UPDATE\n", __func__, ret);
			goto err;
		}

		break;
#endif
	case FPP_ACTION_DEREGISTER:
	
		cmm_print(DEBUG_COMMAND, "Send CMD_VLAN_ENTRY ACTION_DEREGISTER\n");

		ret = fci_write(fci_handle, FPP_CMD_VLAN_ENTRY, sizeof(fpp_vlan_cmd_t), (unsigned short *) &cmd);
		if ((ret == FPP_ERR_OK) || (ret == FPP_ERR_VLAN_ENTRY_NOT_FOUND))
		{
			itf->flags &= ~FPP_PROGRAMMED;
		}
		else
		{
			cmm_print(DEBUG_ERROR, "%s: Error %d while sending CMD_VLAN_ENTRY, ACTION_DEREGISTER\n", __func__, ret);
			goto out;
		}

		break;

	default:
		cmm_print(DEBUG_ERROR, "%s: unknown CMD_VLAN_ENTRY action %x\n", __func__, action);
		ret = CMMD_ERR_UNKNOWN_ACTION;
		break;
	}

out:
	return ret;
}

/*****************************************************************
* cmmVlanReset
* 
*
*
******************************************************************/
void cmmVlanReset(FCI_CLIENT *fci_handle)
{
	struct list_head *entry;
	struct interface *itf;
	short ret;
	int i;

	// Send message to forward engine
	cmm_print(DEBUG_COMMAND, "Send CMD_VLAN_RESET\n");

	__pthread_mutex_lock(&itf_table.lock);

	ret = fci_write(fci_handle, FPP_CMD_VLAN_RESET, 0, NULL); 
	if (ret == FPP_ERR_OK)
	{
		for (i = 0; i < ITF_HASH_TABLE_SIZE; i++)
		{
			for (entry = list_first(&itf_table.hash[i]); entry != &itf_table.hash[i]; entry = list_next(entry))
			{
				itf = container_of(entry, struct interface, list);

				if (!__itf_is_vlan(itf))
					continue;

				itf->flags &= ~FPP_PROGRAMMED;
			}
		}
	}
	else
	{
		cmm_print(DEBUG_ERROR, "%s: Error %d while sending CMD_VLAN_RESET\n", __func__, ret);
	}

	__pthread_mutex_unlock(&itf_table.lock);
}

/*****************************************************************
* cmmVlanCheckPolicy
* check if it is allowable to create device with given name
* 0 means prohibited
* non-zero means allowed
******************************************************************/
int cmmVlanCheckPolicy(struct interface *itf)
{
	// Full implementation will query allow list for prohibit policy
	// and allow list for prohibit policy here
	if (globalConf.vlan_policy != MANUAL) 
		return 1;

	return 0;
}

/*****************************************************************
* cmmVlanLocalShow
*
*
******************************************************************/
int cmmVlanLocalShow(struct cli_def *cli, char *command, char *argv[], int argc)
{
	struct list_head *entry;
	struct interface *itf;
	char ifname[IFNAMSIZ], phys_ifname[IFNAMSIZ];
	int i;

	for (i = 0; i < ITF_HASH_TABLE_SIZE; i++)
	{
		__pthread_mutex_lock(&itf_table.lock);

		for (entry = list_first(&itf_table.hash[i]); entry != &itf_table.hash[i]; entry = list_next(entry))
		{
			itf = container_of(entry, struct interface, list);

			if (!__itf_is_vlan(itf))
				continue;

			cli_print(cli, "Interface: %s, VLAN Id: %4d, physical Interface: %s, Flags: %x", if_indextoname(itf->ifindex, ifname), itf->vlan_id, if_indextoname(itf->phys_ifindex, phys_ifname), itf->flags);

		}

		__pthread_mutex_unlock(&itf_table.lock);
	}

	return CLI_OK;
}

int vlanAddProcess(daemon_handle_t daemon_handle, int argc, char *argv[])
{
	unsigned char rspbuf[512];
	int rsplen;
	cmmd_vlan_cmd_t cmd;

	if (argc < 1)
		goto usage;

	cmd.action = CMMD_ACTION_REGISTER;
	cmd.vlan_id = 0;
	strncpy(cmd.vlan_ifname, argv[0], IFNAMSIZ);
	cmd.vlan_phy_ifname[0] = 0;

	if (((rsplen = cmmSendToDaemon(daemon_handle, CMMD_CMD_VLAN_ENTRY, &cmd, sizeof(cmd), rspbuf)) < sizeof(unsigned short)) ||
	     cmmDaemonCmdRC(rspbuf))
	{
		cmm_print(DEBUG_ERROR, "Error sending CMD_VLAN_ENTRY Register\n");
		/*  break; */ return 0;
	}

	return 0;

usage:
	cmm_print(DEBUG_ERROR, "Usage: vlan add ifname.vlanid\n");
	return 0;
}

int vlanDeleteProcess(daemon_handle_t daemon_handle, int argc, char *argv[])
{
	unsigned char rspbuf[512];
	int rsplen;
	cmmd_vlan_cmd_t cmd;

	if (argc < 1)
		goto usage;

	cmd.action = CMMD_ACTION_DEREGISTER;
	cmd.vlan_id = 0;
	strncpy(cmd.vlan_ifname, argv[0], IFNAMSIZ);
	cmd.vlan_phy_ifname[0] = 0;

	if (((rsplen = cmmSendToDaemon(daemon_handle, CMMD_CMD_VLAN_ENTRY, &cmd, sizeof(cmd), rspbuf)) < sizeof(unsigned short)) ||
	     cmmDaemonCmdRC(rspbuf))
	{
		cmm_print(DEBUG_ERROR, "Error sending CMD_VLAN_ENTRY DeRegister\n");
		return 0;
	}

	return 0;

usage:
	cmm_print(DEBUG_ERROR, "Usage: vlan delete ifname.vlanid\n");
	return 0;
}

static int vlanShowProcess(daemon_handle_t daemon_handle, int argc, char *argv[])
{
	unsigned char rspbuf[512]; 
	int rsplen;
	cmmd_vlan_cmd_t cmd;
	cmmd_vlan_response_t *pqrsp;
	int skipcount = 0;
  
	do {
		memset(&cmd, 0, sizeof(cmd));
		cmd.action = CMMD_ACTION_QUERY_LOCAL;
		cmd.vlan_id = skipcount;

		pqrsp = (cmmd_vlan_response_t *) (rspbuf + 4);

		if (((rsplen = cmmSendToDaemon(daemon_handle, CMMD_CMD_VLAN_ENTRY, &cmd, sizeof(cmd), rspbuf)) < sizeof(unsigned short)) ||
		    cmmDaemonCmdRC(rspbuf))
		{
			cmm_print(DEBUG_STDOUT, "No vlans defined.\n");
			break;
		}

		rsplen -= 4;

		while (rsplen >= sizeof(*pqrsp))
		{
			cmm_print(DEBUG_STDOUT, "Interface: %s, VLAN Id: %d, physical Interface: %s\n",
				pqrsp->vlan_ifname,
				pqrsp->vlan_id,
				pqrsp->vlan_phy_if_name);

			rsplen -= sizeof(*pqrsp);
			pqrsp += 1;
			skipcount += 1;
		}

		if ((rsplen & 1) == 0)
			break;
	} while(1);

	return 0;
}

/*
** cmmVlanClient
** Client side demux - check input and find client side processor for it
*/
int cmmVlanClient(int argc, char **argv, int firstarg, daemon_handle_t daemon_handle)
{
	if (argc <= firstarg)
		goto usage;

	if (strncasecmp(argv[firstarg], "add", 1) == 0)
		return vlanAddProcess(daemon_handle, argc - firstarg - 1, &argv[firstarg + 1]);
	else if (strncasecmp(argv[firstarg], "delete", 1) == 0)
		return vlanDeleteProcess(daemon_handle, argc - firstarg - 1, &argv[firstarg + 1]);
	else if (strncasecmp(argv[firstarg], "show", 1) == 0)
		return vlanShowProcess(daemon_handle, argc - firstarg - 1, &argv[firstarg + 1]);

	return 0;

usage:
	cmm_print(DEBUG_ERROR, "Usage:\n\tvlan [add|delete] ifname.vlanid\n\tvlan show\n");
	return 0;  
}

/*
** cmmVlanProcessClientCmd
** Daemon side demux.
** receives command from client side, processes it and sends response back.
** Return code is a length of a response in bytes, not including 2 bytes of command rc.
** To prevent daemon issuing commands to fpp - return code must be greater then 1
*/
int cmmVlanProcessClientCmd(FCI_CLIENT *fci_handle, int function_code, u_int8_t *cmd_buf, u_int16_t cmd_len, u_int16_t *res_buf, u_int16_t *res_len)
{
	cmmd_vlan_cmd_t *pcmd = (fpp_vlan_cmd_t *) cmd_buf;
	cmmd_vlan_response_t *pqrsp;
	struct interface *itf;
	struct list_head *entry;
	int skipcount, len, i;
	int rc = 0;

	res_buf[0] = CMMD_ERR_OK;

	__pthread_mutex_lock(&itf_table.lock);

	switch (pcmd->action)
	{
	case CMMD_ACTION_REGISTER:
		*res_len = 2;

		itf = __itf_find(if_nametoindex(pcmd->vlan_ifname));
		if (!itf)
		{
			res_buf[0] = CMMD_ERR_WRONG_COMMAND_PARAM;
			break;
		}

		if (!__itf_is_vlan(itf) || !__itf_is_up(itf))
		{
			res_buf[0] = CMMD_ERR_NOT_CONFIGURED;
			break;
		}

		rc = cmmFeVLANUpdate(fci_handle, ADD, itf);
		if (rc > 0)
		{
			res_buf[0] = rc;
			rc = 0;
		}

		break;

	case CMMD_ACTION_DEREGISTER:
		*res_len = 2;

		itf = __itf_find(if_nametoindex(pcmd->vlan_ifname));
		if (!itf)
		{
			res_buf[0] = CMMD_ERR_WRONG_COMMAND_PARAM;
			break;
		}

		if (!__itf_is_vlan(itf))
		{
			res_buf[0] = CMMD_ERR_NOT_CONFIGURED;
			break;
		}

		rc = cmmFeVLANUpdate(fci_handle, REMOVE, itf);
		if (rc > 0)
		{
			res_buf[0] = rc;
			rc = 0;
		}

		break;

	case CMMD_ACTION_QUERY_LOCAL:

		skipcount = pcmd->vlan_id;
		len = 4;
		pqrsp = (cmmd_vlan_response_t *)((char*)res_buf + 4);

		for (i = 0; i < ITF_HASH_TABLE_SIZE; i++)
		{
			for (entry = list_first(&itf_table.hash[i]); entry != &itf_table.hash[i]; entry = list_next(entry))
			{
				itf = container_of(entry, struct interface, list);

				if (!__itf_is_vlan(itf))
					continue;

				if (skipcount <= 0)
				{
					if_indextoname(itf->ifindex, pqrsp->vlan_ifname);
					pqrsp->vlan_id = itf->vlan_id;
					if_indextoname(itf->phys_ifindex, pqrsp->vlan_phy_if_name);
					len += sizeof(*pqrsp);
					pqrsp += 1;

					if (len + sizeof(*pqrsp) >= *res_len)
					{
						
						len += 1; // odd length means that there are more entries to report

						goto out;
					}
				} else {
					skipcount--;
				}
			}
		}

	out:
		*res_len = len;

		break;
 	case CMMD_ACTION_QUERY:
  	case CMMD_ACTION_QUERY_CONT:
       		 rc = fci_cmd(fci_handle, function_code, (u_int16_t*)cmd_buf, cmd_len, res_buf, res_len);
		 break;

	default:
		res_buf[0] = CMMD_ERR_UNKNOWN_ACTION;
		*res_len = 2;
		break;
	}

	__pthread_mutex_unlock(&itf_table.lock);
	return rc;
}

/*****************************************************************
 * * cmmVlanQuery
 * *
 * *
 * ******************************************************************/
int cmmVlanQuery(char ** keywords, int tabStart, daemon_handle_t daemon_handle)
{
        int rcvBytes = 0;
        char rcvBuffer[256];
        short rc;
        int count = 0;
        cmmd_vlan_cmd_t* pVlanCmd = (cmmd_vlan_cmd_t *) rcvBuffer;

        pVlanCmd->action = CMMD_ACTION_QUERY;
        rcvBytes = cmmSendToDaemon(daemon_handle, CMMD_CMD_VLAN_ENTRY, pVlanCmd, 
                                  sizeof(cmmd_vlan_cmd_t) , rcvBuffer);

        if (rcvBytes < sizeof(cmmd_vlan_cmd_t) + sizeof(unsigned short)) {
                rc = (rcvBytes < sizeof(unsigned short) ) ? 0 : 
                                               *((unsigned short *) rcvBuffer);
                if (rc == CMMD_ERR_UNKNOWN_ACTION) {
                    cmm_print(DEBUG_STDERR, 
                         "ERROR: FPP VLANP does not support ACTION_QUERY\n");
                } else if (rc == CMMD_ERR_VLAN_ENTRY_NOT_FOUND) {
                    cmm_print(DEBUG_STDERR, "ERROR: FPP VLAN table empty\n");
                } else {
                    cmm_print(DEBUG_STDERR, 
                            "ERROR: Unexpected result returned from FPP rc:%d\n", rc);
                }
                return CLI_OK;
            }
            cmm_print(DEBUG_STDOUT, "VLAN interfaces:\n");
            do {
			cmm_print(DEBUG_STDOUT, 
                         "Interface: %s, VLAN Id  : %4d,  physical Interface: %s \n",
                          pVlanCmd->vlan_ifname, pVlanCmd->vlan_id,
			pVlanCmd->vlan_phy_ifname);
                	count++;
                	pVlanCmd->action = CMMD_ACTION_QUERY_CONT;
			rcvBytes = cmmSendToDaemon(daemon_handle, CMMD_CMD_VLAN_ENTRY, pVlanCmd,
                       		           sizeof(cmmd_vlan_cmd_t) , rcvBuffer);
           }while (rcvBytes >= sizeof(cmmd_vlan_cmd_t) + sizeof(unsigned short));
           cmm_print(DEBUG_STDOUT, "Total VLAN Entries:%d\n", count);

        return CLI_OK;
} 
