/*
 * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org).
 * Licensed under the GPL.
 */

#include <stddef.h>
#include <errno.h>
#include <libvdeplug.h>
#include "kern_constants.h"
#include "net_user.h"
#include "um_malloc.h"
#include "user.h"
#include "vde.h"

static int vde_user_init(void *data, void *dev)
{
	struct vde_data *pri = data;
	VDECONN *conn = NULL;
	int err = -EINVAL;

	pri->dev = dev;

	conn = vde_open(pri->vde_switch, pri->descr, pri->args);

	if (conn == NULL) {
		err = -errno;
		printk(UM_KERN_ERR "vde_user_init: vde_open failed, "
		       "errno = %d\n", errno);
		return err;
	}

	printk(UM_KERN_INFO "vde backend - connection opened\n");

	pri->conn = conn;

	return 0;
}

static int vde_user_open(void *data)
{
	struct vde_data *pri = data;

	if (pri->conn != NULL)
		return vde_datafd(pri->conn);

	printk(UM_KERN_WARNING "vde_open - we have no VDECONN to open");
	return -EINVAL;
}

static void vde_remove(void *data)
{
	struct vde_data *pri = data;

	if (pri->conn != NULL) {
		printk(UM_KERN_INFO "vde backend - closing connection\n");
		vde_close(pri->conn);
		pri->conn = NULL;
		kfree(pri->args);
		pri->args = NULL;
		return;
	}

	printk(UM_KERN_WARNING "vde_remove - we have no VDECONN to remove");
}

const struct net_user_info vde_user_info = {
	.init		= vde_user_init,
	.open		= vde_user_open,
	.close	 	= NULL,
	.remove	 	= vde_remove,
	.add_address	= NULL,
	.delete_address = NULL,
	.mtu		= ETH_MAX_PACKET,
	.max_packet	= ETH_MAX_PACKET + ETH_HEADER_OTHER,
};

void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init)
{
	struct vde_open_args *args;

	vpri->args = kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL);
	if (vpri->args == NULL) {
		printk(UM_KERN_ERR "vde_init_libstuff - vde_open_args"
		       "allocation failed");
		return;
	}

	args = vpri->args;

	args->port = init->port;
	args->group = init->group;
	args->mode = init->mode ? init->mode : 0700;

	args->port ?  printk(UM_KERN_INFO "port %d", args->port) :
		printk(UM_KERN_INFO "undefined port");
}

int vde_user_read(void *conn, void *buf, int len)
{
	VDECONN *vconn = conn;
	int rv;

	if (vconn == NULL)
		return 0;

	rv = vde_recv(vconn, buf, len, 0);
	if (rv < 0) {
		if (errno == EAGAIN)
			return 0;
		return -errno;
	}
	else if (rv == 0)
		return -ENOTCONN;

	return rv;
}

int vde_user_write(void *conn, void *buf, int len)
{
	VDECONN *vconn = conn;

	if (vconn == NULL)
		return 0;

	return vde_send(vconn, buf, len, 0);
}

