ethertap_kern.c revision 5e7672ec3f059f764fcc5c78216e24bb16c44dba
1/*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
3 * James Leu (jleu@mindspring.net).
4 * Copyright (C) 2001 by various other people who didn't put their name here.
5 * Licensed under the GPL.
6 */
7
8#include "linux/init.h"
9#include "linux/netdevice.h"
10#include "linux/etherdevice.h"
11#include "net_kern.h"
12#include "net_user.h"
13#include "etap.h"
14
15struct ethertap_init {
16	char *dev_name;
17	char *gate_addr;
18};
19
20static void etap_init(struct net_device *dev, void *data)
21{
22	struct uml_net_private *pri;
23	struct ethertap_data *epri;
24	struct ethertap_init *init = data;
25
26	pri = dev->priv;
27	epri = (struct ethertap_data *) pri->user;
28	epri->dev_name = init->dev_name;
29	epri->gate_addr = init->gate_addr;
30	epri->data_fd = -1;
31	epri->control_fd = -1;
32	epri->dev = dev;
33
34	printk("ethertap backend - %s", epri->dev_name);
35	if (epri->gate_addr != NULL)
36		printk(", IP = %s", epri->gate_addr);
37	printk("\n");
38}
39
40static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
41{
42	int len;
43
44	*skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
45	if(*skb == NULL) return(-ENOMEM);
46	len = net_recvfrom(fd, (*skb)->mac.raw,
47			   (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
48	if(len <= 0) return(len);
49	skb_pull(*skb, 2);
50	len -= 2;
51	return(len);
52}
53
54static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
55{
56	if(skb_headroom(*skb) < 2){
57	  	struct sk_buff *skb2;
58
59		skb2 = skb_realloc_headroom(*skb, 2);
60		dev_kfree_skb(*skb);
61		if (skb2 == NULL) return(-ENOMEM);
62		*skb = skb2;
63	}
64	skb_push(*skb, 2);
65	return(net_send(fd, (*skb)->data, (*skb)->len));
66}
67
68const struct net_kern_info ethertap_kern_info = {
69	.init			= etap_init,
70	.protocol		= eth_protocol,
71	.read			= etap_read,
72	.write 			= etap_write,
73};
74
75int ethertap_setup(char *str, char **mac_out, void *data)
76{
77	struct ethertap_init *init = data;
78
79	*init = ((struct ethertap_init)
80		{ .dev_name 	= NULL,
81		  .gate_addr 	= NULL });
82	if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
83			    &init->gate_addr))
84		return(0);
85	if(init->dev_name == NULL){
86		printk("ethertap_setup : Missing tap device name\n");
87		return(0);
88	}
89
90	return(1);
91}
92
93static struct transport ethertap_transport = {
94	.list 		= LIST_HEAD_INIT(ethertap_transport.list),
95	.name 		= "ethertap",
96	.setup  	= ethertap_setup,
97	.user 		= &ethertap_user_info,
98	.kern 		= &ethertap_kern_info,
99	.private_size 	= sizeof(struct ethertap_data),
100};
101
102static int register_ethertap(void)
103{
104	register_transport(&ethertap_transport);
105	return 0;
106}
107
108__initcall(register_ethertap);
109