1/* 2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 3 * Licensed under the GPL 4 */ 5 6#include "linux/stddef.h" 7#include "linux/netdevice.h" 8#include "linux/etherdevice.h" 9#include "linux/skbuff.h" 10#include "linux/init.h" 11#include "asm/errno.h" 12#include "net_kern.h" 13#include "net_user.h" 14#include "tuntap.h" 15 16struct tuntap_init { 17 char *dev_name; 18 char *gate_addr; 19}; 20 21static void tuntap_init(struct net_device *dev, void *data) 22{ 23 struct uml_net_private *pri; 24 struct tuntap_data *tpri; 25 struct tuntap_init *init = data; 26 27 pri = dev->priv; 28 tpri = (struct tuntap_data *) pri->user; 29 tpri->dev_name = init->dev_name; 30 tpri->fixed_config = (init->dev_name != NULL); 31 tpri->gate_addr = init->gate_addr; 32 tpri->fd = -1; 33 tpri->dev = dev; 34 35 printk("TUN/TAP backend - "); 36 if (tpri->gate_addr != NULL) 37 printk("IP = %s", tpri->gate_addr); 38 printk("\n"); 39} 40 41static int tuntap_read(int fd, struct sk_buff **skb, 42 struct uml_net_private *lp) 43{ 44 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 45 if(*skb == NULL) return(-ENOMEM); 46 return(net_read(fd, skb_mac_header(*skb), 47 (*skb)->dev->mtu + ETH_HEADER_OTHER)); 48} 49 50static int tuntap_write(int fd, struct sk_buff **skb, 51 struct uml_net_private *lp) 52{ 53 return(net_write(fd, (*skb)->data, (*skb)->len)); 54} 55 56const struct net_kern_info tuntap_kern_info = { 57 .init = tuntap_init, 58 .protocol = eth_protocol, 59 .read = tuntap_read, 60 .write = tuntap_write, 61}; 62 63int tuntap_setup(char *str, char **mac_out, void *data) 64{ 65 struct tuntap_init *init = data; 66 67 *init = ((struct tuntap_init) 68 { .dev_name = NULL, 69 .gate_addr = NULL }); 70 if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out, 71 &init->gate_addr)) 72 return(0); 73 74 return(1); 75} 76 77static struct transport tuntap_transport = { 78 .list = LIST_HEAD_INIT(tuntap_transport.list), 79 .name = "tuntap", 80 .setup = tuntap_setup, 81 .user = &tuntap_user_info, 82 .kern = &tuntap_kern_info, 83 .private_size = sizeof(struct tuntap_data), 84 .setup_size = sizeof(struct tuntap_init), 85}; 86 87static int register_tuntap(void) 88{ 89 register_transport(&tuntap_transport); 90 return 0; 91} 92 93late_initcall(register_tuntap); 94