ethertap_kern.c 2.3 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
J
Jeff Dike 已提交
2
 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
L
Linus Torvalds 已提交
3
 * James Leu (jleu@mindspring.net).
J
Jeff Dike 已提交
4
 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
L
Linus Torvalds 已提交
5 6 7 8 9
 * Copyright (C) 2001 by various other people who didn't put their name here.
 * Licensed under the GPL.
 */

#include "linux/init.h"
J
Jeff Dike 已提交
10
#include <linux/netdevice.h>
L
Linus Torvalds 已提交
11
#include "etap.h"
J
Jeff Dike 已提交
12
#include "net_kern.h"
L
Linus Torvalds 已提交
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

struct ethertap_init {
	char *dev_name;
	char *gate_addr;
};

static void etap_init(struct net_device *dev, void *data)
{
	struct uml_net_private *pri;
	struct ethertap_data *epri;
	struct ethertap_init *init = data;

	pri = dev->priv;
	epri = (struct ethertap_data *) pri->user;
	epri->dev_name = init->dev_name;
	epri->gate_addr = init->gate_addr;
	epri->data_fd = -1;
	epri->control_fd = -1;
	epri->dev = dev;

	printk("ethertap backend - %s", epri->dev_name);
	if (epri->gate_addr != NULL)
		printk(", IP = %s", epri->gate_addr);
	printk("\n");
}

J
Jeff Dike 已提交
39
static int etap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
L
Linus Torvalds 已提交
40 41 42
{
	int len;

J
Jeff Dike 已提交
43 44
	len = net_recvfrom(fd, skb_mac_header(skb),
			   skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP);
J
Jeff Dike 已提交
45
	if (len <= 0)
J
Jeff Dike 已提交
46 47 48
		return(len);

	skb_pull(skb, 2);
L
Linus Torvalds 已提交
49
	len -= 2;
J
Jeff Dike 已提交
50
	return len;
L
Linus Torvalds 已提交
51 52
}

J
Jeff Dike 已提交
53
static int etap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
L
Linus Torvalds 已提交
54
{
J
Jeff Dike 已提交
55 56
	skb_push(skb, 2);
	return net_send(fd, skb->data, skb->len);
L
Linus Torvalds 已提交
57 58
}

J
Jeff Dike 已提交
59
const struct net_kern_info ethertap_kern_info = {
L
Linus Torvalds 已提交
60 61 62 63 64 65 66 67 68 69 70 71 72
	.init			= etap_init,
	.protocol		= eth_protocol,
	.read			= etap_read,
	.write 			= etap_write,
};

int ethertap_setup(char *str, char **mac_out, void *data)
{
	struct ethertap_init *init = data;

	*init = ((struct ethertap_init)
		{ .dev_name 	= NULL,
		  .gate_addr 	= NULL });
J
Jeff Dike 已提交
73
	if (tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
L
Linus Torvalds 已提交
74
			    &init->gate_addr))
J
Jeff Dike 已提交
75 76 77 78
		return 0;
	if (init->dev_name == NULL) {
		printk(KERN_ERR "ethertap_setup : Missing tap device name\n");
		return 0;
L
Linus Torvalds 已提交
79 80
	}

J
Jeff Dike 已提交
81
	return 1;
L
Linus Torvalds 已提交
82 83 84 85 86 87 88 89 90
}

static struct transport ethertap_transport = {
	.list 		= LIST_HEAD_INIT(ethertap_transport.list),
	.name 		= "ethertap",
	.setup  	= ethertap_setup,
	.user 		= &ethertap_user_info,
	.kern 		= &ethertap_kern_info,
	.private_size 	= sizeof(struct ethertap_data),
J
Jeff Dike 已提交
91
	.setup_size 	= sizeof(struct ethertap_init),
L
Linus Torvalds 已提交
92 93 94 95 96
};

static int register_ethertap(void)
{
	register_transport(&ethertap_transport);
97
	return 0;
L
Linus Torvalds 已提交
98 99
}

100
late_initcall(register_ethertap);