11da177e4SLinus Torvalds /* 2*cd1ae0e4SJeff Dike * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 31da177e4SLinus Torvalds * Licensed under the GPL 41da177e4SLinus Torvalds */ 51da177e4SLinus Torvalds 6*cd1ae0e4SJeff Dike #include <linux/netdevice.h> 7*cd1ae0e4SJeff Dike #include <linux/init.h> 8*cd1ae0e4SJeff Dike #include <linux/skbuff.h> 9*cd1ae0e4SJeff Dike #include <asm/errno.h> 101da177e4SLinus Torvalds #include "net_kern.h" 111da177e4SLinus Torvalds #include "tuntap.h" 121da177e4SLinus Torvalds 131da177e4SLinus Torvalds struct tuntap_init { 141da177e4SLinus Torvalds char *dev_name; 151da177e4SLinus Torvalds char *gate_addr; 161da177e4SLinus Torvalds }; 171da177e4SLinus Torvalds 181da177e4SLinus Torvalds static void tuntap_init(struct net_device *dev, void *data) 191da177e4SLinus Torvalds { 201da177e4SLinus Torvalds struct uml_net_private *pri; 211da177e4SLinus Torvalds struct tuntap_data *tpri; 221da177e4SLinus Torvalds struct tuntap_init *init = data; 231da177e4SLinus Torvalds 241da177e4SLinus Torvalds pri = dev->priv; 251da177e4SLinus Torvalds tpri = (struct tuntap_data *) pri->user; 261da177e4SLinus Torvalds tpri->dev_name = init->dev_name; 271da177e4SLinus Torvalds tpri->fixed_config = (init->dev_name != NULL); 281da177e4SLinus Torvalds tpri->gate_addr = init->gate_addr; 291da177e4SLinus Torvalds tpri->fd = -1; 301da177e4SLinus Torvalds tpri->dev = dev; 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds printk("TUN/TAP backend - "); 331da177e4SLinus Torvalds if (tpri->gate_addr != NULL) 341da177e4SLinus Torvalds printk("IP = %s", tpri->gate_addr); 351da177e4SLinus Torvalds printk("\n"); 361da177e4SLinus Torvalds } 371da177e4SLinus Torvalds 381da177e4SLinus Torvalds static int tuntap_read(int fd, struct sk_buff **skb, 391da177e4SLinus Torvalds struct uml_net_private *lp) 401da177e4SLinus Torvalds { 411da177e4SLinus Torvalds *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 42*cd1ae0e4SJeff Dike if (*skb == NULL) 43*cd1ae0e4SJeff Dike return -ENOMEM; 44*cd1ae0e4SJeff Dike return net_read(fd, skb_mac_header(*skb), 45*cd1ae0e4SJeff Dike (*skb)->dev->mtu + ETH_HEADER_OTHER); 461da177e4SLinus Torvalds } 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds static int tuntap_write(int fd, struct sk_buff **skb, 491da177e4SLinus Torvalds struct uml_net_private *lp) 501da177e4SLinus Torvalds { 51*cd1ae0e4SJeff Dike return net_write(fd, (*skb)->data, (*skb)->len); 521da177e4SLinus Torvalds } 531da177e4SLinus Torvalds 545e7672ecSJeff Dike const struct net_kern_info tuntap_kern_info = { 551da177e4SLinus Torvalds .init = tuntap_init, 561da177e4SLinus Torvalds .protocol = eth_protocol, 571da177e4SLinus Torvalds .read = tuntap_read, 581da177e4SLinus Torvalds .write = tuntap_write, 591da177e4SLinus Torvalds }; 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds int tuntap_setup(char *str, char **mac_out, void *data) 621da177e4SLinus Torvalds { 631da177e4SLinus Torvalds struct tuntap_init *init = data; 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds *init = ((struct tuntap_init) 661da177e4SLinus Torvalds { .dev_name = NULL, 671da177e4SLinus Torvalds .gate_addr = NULL }); 681da177e4SLinus Torvalds if (tap_setup_common(str, "tuntap", &init->dev_name, mac_out, 691da177e4SLinus Torvalds &init->gate_addr)) 70*cd1ae0e4SJeff Dike return 0; 711da177e4SLinus Torvalds 72*cd1ae0e4SJeff Dike return 1; 731da177e4SLinus Torvalds } 741da177e4SLinus Torvalds 751da177e4SLinus Torvalds static struct transport tuntap_transport = { 761da177e4SLinus Torvalds .list = LIST_HEAD_INIT(tuntap_transport.list), 771da177e4SLinus Torvalds .name = "tuntap", 781da177e4SLinus Torvalds .setup = tuntap_setup, 791da177e4SLinus Torvalds .user = &tuntap_user_info, 801da177e4SLinus Torvalds .kern = &tuntap_kern_info, 811da177e4SLinus Torvalds .private_size = sizeof(struct tuntap_data), 821da177e4SLinus Torvalds .setup_size = sizeof(struct tuntap_init), 831da177e4SLinus Torvalds }; 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds static int register_tuntap(void) 861da177e4SLinus Torvalds { 871da177e4SLinus Torvalds register_transport(&tuntap_transport); 88f4c57a78SJeff Dike return 0; 891da177e4SLinus Torvalds } 901da177e4SLinus Torvalds 918210fd2aSJeff Dike late_initcall(register_tuntap); 92