1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4   */
5  
6  #include <linux/netdevice.h>
7  #include <linux/init.h>
8  #include <linux/skbuff.h>
9  #include <asm/errno.h>
10  #include <net_kern.h>
11  #include "tuntap.h"
12  
13  struct tuntap_init {
14  	char *dev_name;
15  	char *gate_addr;
16  };
17  
tuntap_init(struct net_device * dev,void * data)18  static void tuntap_init(struct net_device *dev, void *data)
19  {
20  	struct uml_net_private *pri;
21  	struct tuntap_data *tpri;
22  	struct tuntap_init *init = data;
23  
24  	pri = netdev_priv(dev);
25  	tpri = (struct tuntap_data *) pri->user;
26  	tpri->dev_name = init->dev_name;
27  	tpri->fixed_config = (init->dev_name != NULL);
28  	tpri->gate_addr = init->gate_addr;
29  	tpri->fd = -1;
30  	tpri->dev = dev;
31  
32  	printk(KERN_INFO "TUN/TAP backend - ");
33  	if (tpri->gate_addr != NULL)
34  		printk(KERN_CONT "IP = %s", tpri->gate_addr);
35  	printk(KERN_CONT "\n");
36  }
37  
tuntap_read(int fd,struct sk_buff * skb,struct uml_net_private * lp)38  static int tuntap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
39  {
40  	return net_read(fd, skb_mac_header(skb),
41  			skb->dev->mtu + ETH_HEADER_OTHER);
42  }
43  
tuntap_write(int fd,struct sk_buff * skb,struct uml_net_private * lp)44  static int tuntap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
45  {
46  	return net_write(fd, skb->data, skb->len);
47  }
48  
49  const struct net_kern_info tuntap_kern_info = {
50  	.init			= tuntap_init,
51  	.protocol		= eth_protocol,
52  	.read			= tuntap_read,
53  	.write 			= tuntap_write,
54  };
55  
tuntap_setup(char * str,char ** mac_out,void * data)56  int tuntap_setup(char *str, char **mac_out, void *data)
57  {
58  	struct tuntap_init *init = data;
59  
60  	*init = ((struct tuntap_init)
61  		{ .dev_name 	= NULL,
62  		  .gate_addr 	= NULL });
63  	if (tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
64  			    &init->gate_addr))
65  		return 0;
66  
67  	return 1;
68  }
69  
70  static struct transport tuntap_transport = {
71  	.list 		= LIST_HEAD_INIT(tuntap_transport.list),
72  	.name 		= "tuntap",
73  	.setup  	= tuntap_setup,
74  	.user 		= &tuntap_user_info,
75  	.kern 		= &tuntap_kern_info,
76  	.private_size 	= sizeof(struct tuntap_data),
77  	.setup_size 	= sizeof(struct tuntap_init),
78  };
79  
register_tuntap(void)80  static int register_tuntap(void)
81  {
82  	register_transport(&tuntap_transport);
83  	return 0;
84  }
85  
86  late_initcall(register_tuntap);
87