1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 3*1da177e4SLinus Torvalds * Licensed under the GPL 4*1da177e4SLinus Torvalds */ 5*1da177e4SLinus Torvalds 6*1da177e4SLinus Torvalds #include "linux/stddef.h" 7*1da177e4SLinus Torvalds #include "linux/netdevice.h" 8*1da177e4SLinus Torvalds #include "linux/etherdevice.h" 9*1da177e4SLinus Torvalds #include "linux/skbuff.h" 10*1da177e4SLinus Torvalds #include "linux/init.h" 11*1da177e4SLinus Torvalds #include "asm/errno.h" 12*1da177e4SLinus Torvalds #include "net_kern.h" 13*1da177e4SLinus Torvalds #include "net_user.h" 14*1da177e4SLinus Torvalds #include "tuntap.h" 15*1da177e4SLinus Torvalds 16*1da177e4SLinus Torvalds struct tuntap_init { 17*1da177e4SLinus Torvalds char *dev_name; 18*1da177e4SLinus Torvalds char *gate_addr; 19*1da177e4SLinus Torvalds }; 20*1da177e4SLinus Torvalds 21*1da177e4SLinus Torvalds static void tuntap_init(struct net_device *dev, void *data) 22*1da177e4SLinus Torvalds { 23*1da177e4SLinus Torvalds struct uml_net_private *pri; 24*1da177e4SLinus Torvalds struct tuntap_data *tpri; 25*1da177e4SLinus Torvalds struct tuntap_init *init = data; 26*1da177e4SLinus Torvalds 27*1da177e4SLinus Torvalds pri = dev->priv; 28*1da177e4SLinus Torvalds tpri = (struct tuntap_data *) pri->user; 29*1da177e4SLinus Torvalds tpri->dev_name = init->dev_name; 30*1da177e4SLinus Torvalds tpri->fixed_config = (init->dev_name != NULL); 31*1da177e4SLinus Torvalds tpri->gate_addr = init->gate_addr; 32*1da177e4SLinus Torvalds tpri->fd = -1; 33*1da177e4SLinus Torvalds tpri->dev = dev; 34*1da177e4SLinus Torvalds 35*1da177e4SLinus Torvalds printk("TUN/TAP backend - "); 36*1da177e4SLinus Torvalds if (tpri->gate_addr != NULL) 37*1da177e4SLinus Torvalds printk("IP = %s", tpri->gate_addr); 38*1da177e4SLinus Torvalds printk("\n"); 39*1da177e4SLinus Torvalds } 40*1da177e4SLinus Torvalds 41*1da177e4SLinus Torvalds static int tuntap_read(int fd, struct sk_buff **skb, 42*1da177e4SLinus Torvalds struct uml_net_private *lp) 43*1da177e4SLinus Torvalds { 44*1da177e4SLinus Torvalds *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 45*1da177e4SLinus Torvalds if(*skb == NULL) return(-ENOMEM); 46*1da177e4SLinus Torvalds return(net_read(fd, (*skb)->mac.raw, 47*1da177e4SLinus Torvalds (*skb)->dev->mtu + ETH_HEADER_OTHER)); 48*1da177e4SLinus Torvalds } 49*1da177e4SLinus Torvalds 50*1da177e4SLinus Torvalds static int tuntap_write(int fd, struct sk_buff **skb, 51*1da177e4SLinus Torvalds struct uml_net_private *lp) 52*1da177e4SLinus Torvalds { 53*1da177e4SLinus Torvalds return(net_write(fd, (*skb)->data, (*skb)->len)); 54*1da177e4SLinus Torvalds } 55*1da177e4SLinus Torvalds 56*1da177e4SLinus Torvalds struct net_kern_info tuntap_kern_info = { 57*1da177e4SLinus Torvalds .init = tuntap_init, 58*1da177e4SLinus Torvalds .protocol = eth_protocol, 59*1da177e4SLinus Torvalds .read = tuntap_read, 60*1da177e4SLinus Torvalds .write = tuntap_write, 61*1da177e4SLinus Torvalds }; 62*1da177e4SLinus Torvalds 63*1da177e4SLinus Torvalds int tuntap_setup(char *str, char **mac_out, void *data) 64*1da177e4SLinus Torvalds { 65*1da177e4SLinus Torvalds struct tuntap_init *init = data; 66*1da177e4SLinus Torvalds 67*1da177e4SLinus Torvalds *init = ((struct tuntap_init) 68*1da177e4SLinus Torvalds { .dev_name = NULL, 69*1da177e4SLinus Torvalds .gate_addr = NULL }); 70*1da177e4SLinus Torvalds if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out, 71*1da177e4SLinus Torvalds &init->gate_addr)) 72*1da177e4SLinus Torvalds return(0); 73*1da177e4SLinus Torvalds 74*1da177e4SLinus Torvalds return(1); 75*1da177e4SLinus Torvalds } 76*1da177e4SLinus Torvalds 77*1da177e4SLinus Torvalds static struct transport tuntap_transport = { 78*1da177e4SLinus Torvalds .list = LIST_HEAD_INIT(tuntap_transport.list), 79*1da177e4SLinus Torvalds .name = "tuntap", 80*1da177e4SLinus Torvalds .setup = tuntap_setup, 81*1da177e4SLinus Torvalds .user = &tuntap_user_info, 82*1da177e4SLinus Torvalds .kern = &tuntap_kern_info, 83*1da177e4SLinus Torvalds .private_size = sizeof(struct tuntap_data), 84*1da177e4SLinus Torvalds .setup_size = sizeof(struct tuntap_init), 85*1da177e4SLinus Torvalds }; 86*1da177e4SLinus Torvalds 87*1da177e4SLinus Torvalds static int register_tuntap(void) 88*1da177e4SLinus Torvalds { 89*1da177e4SLinus Torvalds register_transport(&tuntap_transport); 90*1da177e4SLinus Torvalds return(1); 91*1da177e4SLinus Torvalds } 92*1da177e4SLinus Torvalds 93*1da177e4SLinus Torvalds __initcall(register_tuntap); 94*1da177e4SLinus Torvalds 95*1da177e4SLinus Torvalds /* 96*1da177e4SLinus Torvalds * Overrides for Emacs so that we follow Linus's tabbing style. 97*1da177e4SLinus Torvalds * Emacs will notice this stuff at the end of the file and automatically 98*1da177e4SLinus Torvalds * adjust the settings for this buffer only. This must remain at the end 99*1da177e4SLinus Torvalds * of the file. 100*1da177e4SLinus Torvalds * --------------------------------------------------------------------------- 101*1da177e4SLinus Torvalds * Local variables: 102*1da177e4SLinus Torvalds * c-file-style: "linux" 103*1da177e4SLinus Torvalds * End: 104*1da177e4SLinus Torvalds */ 105