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 
15 struct ethertap_init {
16 	char *dev_name;
17 	char *gate_addr;
18 };
19 
20 static 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 
40 static 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 
54 static 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 
68 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 
75 int 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 
93 static 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 
102 static int register_ethertap(void)
103 {
104 	register_transport(&ethertap_transport);
105 	return(1);
106 }
107 
108 __initcall(register_ethertap);
109 
110 /*
111  * Overrides for Emacs so that we follow Linus's tabbing style.
112  * Emacs will notice this stuff at the end of the file and automatically
113  * adjust the settings for this buffer only.  This must remain at the end
114  * of the file.
115  * ---------------------------------------------------------------------------
116  * Local variables:
117  * c-file-style: "linux"
118  * End:
119  */
120