xref: /linux/arch/um/os-Linux/drivers/ethertap_kern.c (revision daa2be74b1b2302004945b2a5e32424e177cc7da)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
4  * James Leu (jleu@mindspring.net).
5  * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
6  * Copyright (C) 2001 by various other people who didn't put their name here.
7  */
8 
9 #include <linux/init.h>
10 #include <linux/netdevice.h>
11 #include "etap.h"
12 #include <net_kern.h>
13 
14 struct ethertap_init {
15 	char *dev_name;
16 	char *gate_addr;
17 };
18 
19 static void etap_init(struct net_device *dev, void *data)
20 {
21 	struct uml_net_private *pri;
22 	struct ethertap_data *epri;
23 	struct ethertap_init *init = data;
24 
25 	pri = netdev_priv(dev);
26 	epri = (struct ethertap_data *) pri->user;
27 	epri->dev_name = init->dev_name;
28 	epri->gate_addr = init->gate_addr;
29 	epri->data_fd = -1;
30 	epri->control_fd = -1;
31 	epri->dev = dev;
32 
33 	printk(KERN_INFO "ethertap backend - %s", epri->dev_name);
34 	if (epri->gate_addr != NULL)
35 		printk(KERN_CONT ", IP = %s", epri->gate_addr);
36 	printk(KERN_CONT "\n");
37 }
38 
39 static int etap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
40 {
41 	int len;
42 
43 	len = net_recvfrom(fd, skb_mac_header(skb),
44 			   skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP);
45 	if (len <= 0)
46 		return(len);
47 
48 	skb_pull(skb, 2);
49 	len -= 2;
50 	return len;
51 }
52 
53 static int etap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
54 {
55 	skb_push(skb, 2);
56 	return net_send(fd, skb->data, skb->len);
57 }
58 
59 const struct net_kern_info ethertap_kern_info = {
60 	.init			= etap_init,
61 	.protocol		= eth_protocol,
62 	.read			= etap_read,
63 	.write 			= etap_write,
64 };
65 
66 static int ethertap_setup(char *str, char **mac_out, void *data)
67 {
68 	struct ethertap_init *init = data;
69 
70 	*init = ((struct ethertap_init)
71 		{ .dev_name 	= NULL,
72 		  .gate_addr 	= NULL });
73 	if (tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
74 			    &init->gate_addr))
75 		return 0;
76 	if (init->dev_name == NULL) {
77 		printk(KERN_ERR "ethertap_setup : Missing tap device name\n");
78 		return 0;
79 	}
80 
81 	return 1;
82 }
83 
84 static struct transport ethertap_transport = {
85 	.list 		= LIST_HEAD_INIT(ethertap_transport.list),
86 	.name 		= "ethertap",
87 	.setup  	= ethertap_setup,
88 	.user 		= &ethertap_user_info,
89 	.kern 		= &ethertap_kern_info,
90 	.private_size 	= sizeof(struct ethertap_data),
91 	.setup_size 	= sizeof(struct ethertap_init),
92 };
93 
94 static int register_ethertap(void)
95 {
96 	register_transport(&ethertap_transport);
97 	return 0;
98 }
99 
100 late_initcall(register_ethertap);
101