xref: /openbmc/linux/arch/um/os-Linux/drivers/tuntap_kern.c (revision cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085)
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