PageRenderTime 60ms CodeModel.GetById 30ms app.highlight 21ms RepoModel.GetById 3ms app.codeStats 1ms

/arch/um/os-Linux/drivers/ethertap_kern.c

https://bitbucket.org/evzijst/gittest
C | 119 lines | 86 code | 17 blank | 16 comment | 11 complexity | 69fa9803ce1f5f006cfccf09faf3a5d4 MD5 | raw file
  1/*
  2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
  3 * James Leu (jleu@mindspring.net).
  4 * Copyright (C) 2001 by various other people who didn't put their name here.
  5 * Licensed under the GPL.
  6 */
  7
  8#include "linux/init.h"
  9#include "linux/netdevice.h"
 10#include "linux/etherdevice.h"
 11#include "net_kern.h"
 12#include "net_user.h"
 13#include "etap.h"
 14
 15struct ethertap_init {
 16	char *dev_name;
 17	char *gate_addr;
 18};
 19
 20static void etap_init(struct net_device *dev, void *data)
 21{
 22	struct uml_net_private *pri;
 23	struct ethertap_data *epri;
 24	struct ethertap_init *init = data;
 25
 26	pri = dev->priv;
 27	epri = (struct ethertap_data *) pri->user;
 28	epri->dev_name = init->dev_name;
 29	epri->gate_addr = init->gate_addr;
 30	epri->data_fd = -1;
 31	epri->control_fd = -1;
 32	epri->dev = dev;
 33
 34	printk("ethertap backend - %s", epri->dev_name);
 35	if (epri->gate_addr != NULL)
 36		printk(", IP = %s", epri->gate_addr);
 37	printk("\n");
 38}
 39
 40static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
 41{
 42	int len;
 43
 44	*skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
 45	if(*skb == NULL) return(-ENOMEM);
 46	len = net_recvfrom(fd, (*skb)->mac.raw, 
 47			   (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
 48	if(len <= 0) return(len);
 49	skb_pull(*skb, 2);
 50	len -= 2;
 51	return(len);
 52}
 53
 54static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
 55{
 56	if(skb_headroom(*skb) < 2){
 57	  	struct sk_buff *skb2;
 58
 59		skb2 = skb_realloc_headroom(*skb, 2);
 60		dev_kfree_skb(*skb);
 61		if (skb2 == NULL) return(-ENOMEM);
 62		*skb = skb2;
 63	}
 64	skb_push(*skb, 2);
 65	return(net_send(fd, (*skb)->data, (*skb)->len));
 66}
 67
 68struct net_kern_info ethertap_kern_info = {
 69	.init			= etap_init,
 70	.protocol		= eth_protocol,
 71	.read			= etap_read,
 72	.write 			= etap_write,
 73};
 74
 75int ethertap_setup(char *str, char **mac_out, void *data)
 76{
 77	struct ethertap_init *init = data;
 78
 79	*init = ((struct ethertap_init)
 80		{ .dev_name 	= NULL,
 81		  .gate_addr 	= NULL });
 82	if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
 83			    &init->gate_addr))
 84		return(0);
 85	if(init->dev_name == NULL){
 86		printk("ethertap_setup : Missing tap device name\n");
 87		return(0);
 88	}
 89
 90	return(1);
 91}
 92
 93static struct transport ethertap_transport = {
 94	.list 		= LIST_HEAD_INIT(ethertap_transport.list),
 95	.name 		= "ethertap",
 96	.setup  	= ethertap_setup,
 97	.user 		= &ethertap_user_info,
 98	.kern 		= &ethertap_kern_info,
 99	.private_size 	= sizeof(struct ethertap_data),
100};
101
102static int register_ethertap(void)
103{
104	register_transport(&ethertap_transport);
105	return(1);
106}
107
108__initcall(register_ethertap);
109
110/*
111 * Overrides for Emacs so that we follow Linus's tabbing style.
112 * Emacs will notice this stuff at the end of the file and automatically
113 * adjust the settings for this buffer only.  This must remain at the end
114 * of the file.
115 * ---------------------------------------------------------------------------
116 * Local variables:
117 * c-file-style: "linux"
118 * End:
119 */