Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
0004  * James Leu (jleu@mindspring.net).
0005  * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
0006  * Copyright (C) 2001 by various other people who didn't put their name here.
0007  */
0008 
0009 #include <linux/init.h>
0010 #include <linux/netdevice.h>
0011 #include "etap.h"
0012 #include <net_kern.h>
0013 
0014 struct ethertap_init {
0015     char *dev_name;
0016     char *gate_addr;
0017 };
0018 
0019 static void etap_init(struct net_device *dev, void *data)
0020 {
0021     struct uml_net_private *pri;
0022     struct ethertap_data *epri;
0023     struct ethertap_init *init = data;
0024 
0025     pri = netdev_priv(dev);
0026     epri = (struct ethertap_data *) pri->user;
0027     epri->dev_name = init->dev_name;
0028     epri->gate_addr = init->gate_addr;
0029     epri->data_fd = -1;
0030     epri->control_fd = -1;
0031     epri->dev = dev;
0032 
0033     printk(KERN_INFO "ethertap backend - %s", epri->dev_name);
0034     if (epri->gate_addr != NULL)
0035         printk(KERN_CONT ", IP = %s", epri->gate_addr);
0036     printk(KERN_CONT "\n");
0037 }
0038 
0039 static int etap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
0040 {
0041     int len;
0042 
0043     len = net_recvfrom(fd, skb_mac_header(skb),
0044                skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP);
0045     if (len <= 0)
0046         return(len);
0047 
0048     skb_pull(skb, 2);
0049     len -= 2;
0050     return len;
0051 }
0052 
0053 static int etap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
0054 {
0055     skb_push(skb, 2);
0056     return net_send(fd, skb->data, skb->len);
0057 }
0058 
0059 const struct net_kern_info ethertap_kern_info = {
0060     .init           = etap_init,
0061     .protocol       = eth_protocol,
0062     .read           = etap_read,
0063     .write          = etap_write,
0064 };
0065 
0066 int ethertap_setup(char *str, char **mac_out, void *data)
0067 {
0068     struct ethertap_init *init = data;
0069 
0070     *init = ((struct ethertap_init)
0071         { .dev_name     = NULL,
0072           .gate_addr    = NULL });
0073     if (tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
0074                 &init->gate_addr))
0075         return 0;
0076     if (init->dev_name == NULL) {
0077         printk(KERN_ERR "ethertap_setup : Missing tap device name\n");
0078         return 0;
0079     }
0080 
0081     return 1;
0082 }
0083 
0084 static struct transport ethertap_transport = {
0085     .list       = LIST_HEAD_INIT(ethertap_transport.list),
0086     .name       = "ethertap",
0087     .setup      = ethertap_setup,
0088     .user       = &ethertap_user_info,
0089     .kern       = &ethertap_kern_info,
0090     .private_size   = sizeof(struct ethertap_data),
0091     .setup_size     = sizeof(struct ethertap_init),
0092 };
0093 
0094 static int register_ethertap(void)
0095 {
0096     register_transport(&ethertap_transport);
0097     return 0;
0098 }
0099 
0100 late_initcall(register_ethertap);