11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 31da177e4SLinus Torvalds * Licensed under the GPL 41da177e4SLinus Torvalds */ 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds #include "linux/stddef.h" 71da177e4SLinus Torvalds #include "linux/netdevice.h" 81da177e4SLinus Torvalds #include "linux/etherdevice.h" 91da177e4SLinus Torvalds #include "linux/skbuff.h" 101da177e4SLinus Torvalds #include "linux/init.h" 111da177e4SLinus Torvalds #include "asm/errno.h" 121da177e4SLinus Torvalds #include "net_kern.h" 131da177e4SLinus Torvalds #include "net_user.h" 141da177e4SLinus Torvalds #include "tuntap.h" 151da177e4SLinus Torvalds 161da177e4SLinus Torvalds struct tuntap_init { 171da177e4SLinus Torvalds char *dev_name; 181da177e4SLinus Torvalds char *gate_addr; 191da177e4SLinus Torvalds }; 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds static void tuntap_init(struct net_device *dev, void *data) 221da177e4SLinus Torvalds { 231da177e4SLinus Torvalds struct uml_net_private *pri; 241da177e4SLinus Torvalds struct tuntap_data *tpri; 251da177e4SLinus Torvalds struct tuntap_init *init = data; 261da177e4SLinus Torvalds 271da177e4SLinus Torvalds pri = dev->priv; 281da177e4SLinus Torvalds tpri = (struct tuntap_data *) pri->user; 291da177e4SLinus Torvalds tpri->dev_name = init->dev_name; 301da177e4SLinus Torvalds tpri->fixed_config = (init->dev_name != NULL); 311da177e4SLinus Torvalds tpri->gate_addr = init->gate_addr; 321da177e4SLinus Torvalds tpri->fd = -1; 331da177e4SLinus Torvalds tpri->dev = dev; 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds printk("TUN/TAP backend - "); 361da177e4SLinus Torvalds if (tpri->gate_addr != NULL) 371da177e4SLinus Torvalds printk("IP = %s", tpri->gate_addr); 381da177e4SLinus Torvalds printk("\n"); 391da177e4SLinus Torvalds } 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds static int tuntap_read(int fd, struct sk_buff **skb, 421da177e4SLinus Torvalds struct uml_net_private *lp) 431da177e4SLinus Torvalds { 441da177e4SLinus Torvalds *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 451da177e4SLinus Torvalds if(*skb == NULL) return(-ENOMEM); 461da177e4SLinus Torvalds return(net_read(fd, (*skb)->mac.raw, 471da177e4SLinus Torvalds (*skb)->dev->mtu + ETH_HEADER_OTHER)); 481da177e4SLinus Torvalds } 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds static int tuntap_write(int fd, struct sk_buff **skb, 511da177e4SLinus Torvalds struct uml_net_private *lp) 521da177e4SLinus Torvalds { 531da177e4SLinus Torvalds return(net_write(fd, (*skb)->data, (*skb)->len)); 541da177e4SLinus Torvalds } 551da177e4SLinus Torvalds 56*5e7672ecSJeff Dike const struct net_kern_info tuntap_kern_info = { 571da177e4SLinus Torvalds .init = tuntap_init, 581da177e4SLinus Torvalds .protocol = eth_protocol, 591da177e4SLinus Torvalds .read = tuntap_read, 601da177e4SLinus Torvalds .write = tuntap_write, 611da177e4SLinus Torvalds }; 621da177e4SLinus Torvalds 631da177e4SLinus Torvalds int tuntap_setup(char *str, char **mac_out, void *data) 641da177e4SLinus Torvalds { 651da177e4SLinus Torvalds struct tuntap_init *init = data; 661da177e4SLinus Torvalds 671da177e4SLinus Torvalds *init = ((struct tuntap_init) 681da177e4SLinus Torvalds { .dev_name = NULL, 691da177e4SLinus Torvalds .gate_addr = NULL }); 701da177e4SLinus Torvalds if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out, 711da177e4SLinus Torvalds &init->gate_addr)) 721da177e4SLinus Torvalds return(0); 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds return(1); 751da177e4SLinus Torvalds } 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds static struct transport tuntap_transport = { 781da177e4SLinus Torvalds .list = LIST_HEAD_INIT(tuntap_transport.list), 791da177e4SLinus Torvalds .name = "tuntap", 801da177e4SLinus Torvalds .setup = tuntap_setup, 811da177e4SLinus Torvalds .user = &tuntap_user_info, 821da177e4SLinus Torvalds .kern = &tuntap_kern_info, 831da177e4SLinus Torvalds .private_size = sizeof(struct tuntap_data), 841da177e4SLinus Torvalds .setup_size = sizeof(struct tuntap_init), 851da177e4SLinus Torvalds }; 861da177e4SLinus Torvalds 871da177e4SLinus Torvalds static int register_tuntap(void) 881da177e4SLinus Torvalds { 891da177e4SLinus Torvalds register_transport(&tuntap_transport); 90f4c57a78SJeff Dike return 0; 911da177e4SLinus Torvalds } 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds __initcall(register_tuntap); 94