vde_kern.c 3.0 KB
Newer Older
J
Jeff Dike 已提交
1 2 3 4 5 6 7 8 9 10
/*
 * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org).
 * Licensed under the GPL.
 *
 * Transport usage:
 *  ethN=vde,<vde_switch>,<mac addr>,<port>,<group>,<mode>,<description>
 *
 */

#include "linux/init.h"
J
Jeff Dike 已提交
11
#include <linux/netdevice.h>
J
Jeff Dike 已提交
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#include "net_kern.h"
#include "net_user.h"
#include "vde.h"

static void vde_init(struct net_device *dev, void *data)
{
	struct vde_init *init = data;
	struct uml_net_private *pri;
	struct vde_data *vpri;

	pri = dev->priv;
	vpri = (struct vde_data *) pri->user;

	vpri->vde_switch = init->vde_switch;
	vpri->descr = init->descr ? init->descr : "UML vde_transport";
	vpri->args = NULL;
	vpri->conn = NULL;
	vpri->dev = dev;

J
Jeff Dike 已提交
31
	printk("vde backend - %s, ", vpri->vde_switch ?
J
Jeff Dike 已提交
32 33 34 35
	       vpri->vde_switch : "(default socket)");

	vde_init_libstuff(vpri, init);

J
Jeff Dike 已提交
36
	printk("\n");
J
Jeff Dike 已提交
37 38
}

J
Jeff Dike 已提交
39
static int vde_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
J
Jeff Dike 已提交
40 41 42
{
	struct vde_data *pri = (struct vde_data *) &lp->user;

J
Jeff Dike 已提交
43 44 45
	if (pri->conn != NULL)
		return vde_user_read(pri->conn, skb_mac_header(skb),
				     skb->dev->mtu + ETH_HEADER_OTHER);
J
Jeff Dike 已提交
46 47 48 49 50

	printk(KERN_ERR "vde_read - we have no VDECONN to read from");
	return -EBADF;
}

J
Jeff Dike 已提交
51
static int vde_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
J
Jeff Dike 已提交
52 53 54 55
{
	struct vde_data *pri = (struct vde_data *) &lp->user;

	if (pri->conn != NULL)
J
Jeff Dike 已提交
56 57
		return vde_user_write((void *)pri->conn, skb->data,
				      skb->len);
J
Jeff Dike 已提交
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129

	printk(KERN_ERR "vde_write - we have no VDECONN to write to");
	return -EBADF;
}

static const struct net_kern_info vde_kern_info = {
	.init			= vde_init,
	.protocol		= eth_protocol,
	.read			= vde_read,
	.write			= vde_write,
};

static int vde_setup(char *str, char **mac_out, void *data)
{
	struct vde_init *init = data;
	char *remain, *port_str = NULL, *mode_str = NULL, *last;

	*init = ((struct vde_init)
		{ .vde_switch		= NULL,
		  .descr		= NULL,
		  .port			= 0,
		  .group		= NULL,
		  .mode			= 0 });

	remain = split_if_spec(str, &init->vde_switch, mac_out, &port_str,
				&init->group, &mode_str, &init->descr, NULL);

	if (remain != NULL)
		printk(KERN_WARNING "vde_setup - Ignoring extra data :"
		       "'%s'\n", remain);

	if (port_str != NULL) {
		init->port = simple_strtoul(port_str, &last, 10);
		if ((*last != '\0') || (last == port_str)) {
			printk(KERN_ERR "vde_setup - Bad port : '%s'\n",
						port_str);
			return 0;
		}
	}

	if (mode_str != NULL) {
		init->mode = simple_strtoul(mode_str, &last, 8);
		if ((*last != '\0') || (last == mode_str)) {
			printk(KERN_ERR "vde_setup - Bad mode : '%s'\n",
						mode_str);
			return 0;
		}
	}

	printk(KERN_INFO "Configured vde device: %s\n", init->vde_switch ?
	       init->vde_switch : "(default socket)");

	return 1;
}

static struct transport vde_transport = {
	.list 		= LIST_HEAD_INIT(vde_transport.list),
	.name 		= "vde",
	.setup  	= vde_setup,
	.user 		= &vde_user_info,
	.kern 		= &vde_kern_info,
	.private_size 	= sizeof(struct vde_data),
	.setup_size 	= sizeof(struct vde_init),
};

static int register_vde(void)
{
	register_transport(&vde_transport);
	return 0;
}

late_initcall(register_vde);