1cd1ae0e4SJeff Dike /* 2cd1ae0e4SJeff Dike * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3cd1ae0e4SJeff Dike * Licensed under the GPL. 4cd1ae0e4SJeff Dike */ 5cd1ae0e4SJeff Dike 6cd1ae0e4SJeff Dike #include <linux/if_arp.h> 71da177e4SLinus Torvalds #include "linux/init.h" 8cd1ae0e4SJeff Dike #include <linux/netdevice.h> 9cd1ae0e4SJeff Dike #include <linux/string.h> 101da177e4SLinus Torvalds #include "net_kern.h" 111da177e4SLinus Torvalds #include "net_user.h" 121da177e4SLinus Torvalds #include "slirp.h" 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds struct slirp_init { 151da177e4SLinus Torvalds struct arg_list_dummy_wrapper argw; /* XXX should be simpler... */ 161da177e4SLinus Torvalds }; 171da177e4SLinus Torvalds 181da177e4SLinus Torvalds void slirp_init(struct net_device *dev, void *data) 191da177e4SLinus Torvalds { 201da177e4SLinus Torvalds struct uml_net_private *private; 211da177e4SLinus Torvalds struct slirp_data *spri; 221da177e4SLinus Torvalds struct slirp_init *init = data; 231da177e4SLinus Torvalds int i; 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds private = dev->priv; 261da177e4SLinus Torvalds spri = (struct slirp_data *) private->user; 27854e981cSPaolo 'Blaisorblade' Giarrusso 28854e981cSPaolo 'Blaisorblade' Giarrusso spri->argw = init->argw; 29854e981cSPaolo 'Blaisorblade' Giarrusso spri->pid = -1; 30854e981cSPaolo 'Blaisorblade' Giarrusso spri->slave = -1; 31854e981cSPaolo 'Blaisorblade' Giarrusso spri->dev = dev; 32854e981cSPaolo 'Blaisorblade' Giarrusso 33854e981cSPaolo 'Blaisorblade' Giarrusso slip_proto_init(&spri->slip); 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds dev->init = NULL; 361da177e4SLinus Torvalds dev->hard_header_len = 0; 371da177e4SLinus Torvalds dev->header_cache_update = NULL; 381da177e4SLinus Torvalds dev->hard_header_cache = NULL; 391da177e4SLinus Torvalds dev->hard_header = NULL; 401da177e4SLinus Torvalds dev->addr_len = 0; 411da177e4SLinus Torvalds dev->type = ARPHRD_SLIP; 421da177e4SLinus Torvalds dev->tx_queue_len = 256; 431da177e4SLinus Torvalds dev->flags = IFF_NOARP; 441da177e4SLinus Torvalds printk("SLIRP backend - command line:"); 45cd1ae0e4SJeff Dike for (i = 0; spri->argw.argv[i] != NULL; i++) 461da177e4SLinus Torvalds printk(" '%s'",spri->argw.argv[i]); 471da177e4SLinus Torvalds printk("\n"); 481da177e4SLinus Torvalds } 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds static unsigned short slirp_protocol(struct sk_buff *skbuff) 511da177e4SLinus Torvalds { 52cd1ae0e4SJeff Dike return htons(ETH_P_IP); 531da177e4SLinus Torvalds } 541da177e4SLinus Torvalds 55*b53f35a8SJeff Dike static int slirp_read(int fd, struct sk_buff *skb, struct uml_net_private *lp) 561da177e4SLinus Torvalds { 57*b53f35a8SJeff Dike return slirp_user_read(fd, skb_mac_header(skb), skb->dev->mtu, 58cd1ae0e4SJeff Dike (struct slirp_data *) &lp->user); 591da177e4SLinus Torvalds } 601da177e4SLinus Torvalds 61*b53f35a8SJeff Dike static int slirp_write(int fd, struct sk_buff *skb, struct uml_net_private *lp) 621da177e4SLinus Torvalds { 63*b53f35a8SJeff Dike return slirp_user_write(fd, skb->data, skb->len, 64cd1ae0e4SJeff Dike (struct slirp_data *) &lp->user); 651da177e4SLinus Torvalds } 661da177e4SLinus Torvalds 675e7672ecSJeff Dike const struct net_kern_info slirp_kern_info = { 681da177e4SLinus Torvalds .init = slirp_init, 691da177e4SLinus Torvalds .protocol = slirp_protocol, 701da177e4SLinus Torvalds .read = slirp_read, 711da177e4SLinus Torvalds .write = slirp_write, 721da177e4SLinus Torvalds }; 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds static int slirp_setup(char *str, char **mac_out, void *data) 751da177e4SLinus Torvalds { 761da177e4SLinus Torvalds struct slirp_init *init = data; 771da177e4SLinus Torvalds int i=0; 781da177e4SLinus Torvalds 79cd1ae0e4SJeff Dike *init = ((struct slirp_init) { .argw = { { "slirp", NULL } } }); 801da177e4SLinus Torvalds 811da177e4SLinus Torvalds str = split_if_spec(str, mac_out, NULL); 821da177e4SLinus Torvalds 83cd1ae0e4SJeff Dike if (str == NULL) /* no command line given after MAC addr */ 84cd1ae0e4SJeff Dike return 1; 851da177e4SLinus Torvalds 861da177e4SLinus Torvalds do { 871da177e4SLinus Torvalds if (i >= SLIRP_MAX_ARGS - 1) { 88cd1ae0e4SJeff Dike printk(KERN_WARNING "slirp_setup: truncating slirp " 89cd1ae0e4SJeff Dike "arguments\n"); 901da177e4SLinus Torvalds break; 911da177e4SLinus Torvalds } 921da177e4SLinus Torvalds init->argw.argv[i++] = str; 931da177e4SLinus Torvalds while(*str && *str!=',') { 94cd1ae0e4SJeff Dike if (*str == '_') 95cd1ae0e4SJeff Dike *str=' '; 961da177e4SLinus Torvalds str++; 971da177e4SLinus Torvalds } 981da177e4SLinus Torvalds if (*str != ',') 991da177e4SLinus Torvalds break; 1001da177e4SLinus Torvalds *str++ = '\0'; 1011da177e4SLinus Torvalds } while (1); 102cd1ae0e4SJeff Dike 1031da177e4SLinus Torvalds init->argw.argv[i] = NULL; 104cd1ae0e4SJeff Dike return 1; 1051da177e4SLinus Torvalds } 1061da177e4SLinus Torvalds 1071da177e4SLinus Torvalds static struct transport slirp_transport = { 1081da177e4SLinus Torvalds .list = LIST_HEAD_INIT(slirp_transport.list), 1091da177e4SLinus Torvalds .name = "slirp", 1101da177e4SLinus Torvalds .setup = slirp_setup, 1111da177e4SLinus Torvalds .user = &slirp_user_info, 1121da177e4SLinus Torvalds .kern = &slirp_kern_info, 1131da177e4SLinus Torvalds .private_size = sizeof(struct slirp_data), 1141da177e4SLinus Torvalds .setup_size = sizeof(struct slirp_init), 1151da177e4SLinus Torvalds }; 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds static int register_slirp(void) 1181da177e4SLinus Torvalds { 1191da177e4SLinus Torvalds register_transport(&slirp_transport); 120f4c57a78SJeff Dike return 0; 1211da177e4SLinus Torvalds } 1221da177e4SLinus Torvalds 1238210fd2aSJeff Dike late_initcall(register_slirp); 124