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