Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / um / os-Linux / drivers / ethertap_kern.c
blob6ae4b19d9f50e3622217ed26b8e7bc9b672fced7
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 */
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"
15 struct ethertap_init {
16 char *dev_name;
17 char *gate_addr;
20 static void etap_init(struct net_device *dev, void *data)
22 struct uml_net_private *pri;
23 struct ethertap_data *epri;
24 struct ethertap_init *init = data;
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;
34 printk("ethertap backend - %s", epri->dev_name);
35 if (epri->gate_addr != NULL)
36 printk(", IP = %s", epri->gate_addr);
37 printk("\n");
40 static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
42 int len;
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);
54 static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
56 if(skb_headroom(*skb) < 2){
57 struct sk_buff *skb2;
59 skb2 = skb_realloc_headroom(*skb, 2);
60 dev_kfree_skb(*skb);
61 if (skb2 == NULL) return(-ENOMEM);
62 *skb = skb2;
64 skb_push(*skb, 2);
65 return(net_send(fd, (*skb)->data, (*skb)->len));
68 struct net_kern_info ethertap_kern_info = {
69 .init = etap_init,
70 .protocol = eth_protocol,
71 .read = etap_read,
72 .write = etap_write,
75 int ethertap_setup(char *str, char **mac_out, void *data)
77 struct ethertap_init *init = data;
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);
90 return(1);
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),
102 static int register_ethertap(void)
104 register_transport(&ethertap_transport);
105 return(1);
108 __initcall(register_ethertap);
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: