Blame view

arch/um/drivers/vde_kern.c 3.02 KB
ad43c3565   Jeff Dike   uml: add VDE netw...
1
2
3
4
5
6
7
8
  /*
   * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org).
   * Licensed under the GPL.
   *
   * Transport usage:
   *  ethN=vde,<vde_switch>,<mac addr>,<port>,<group>,<mode>,<description>
   *
   */
ad43c3565   Jeff Dike   uml: add VDE netw...
9
  #include "linux/init.h"
cd1ae0e49   Jeff Dike   uml: network form...
10
  #include <linux/netdevice.h>
ad43c3565   Jeff Dike   uml: add VDE netw...
11
12
13
14
15
16
17
18
19
  #include "net_kern.h"
  #include "net_user.h"
  #include "vde.h"
  
  static void vde_init(struct net_device *dev, void *data)
  {
  	struct vde_init *init = data;
  	struct uml_net_private *pri;
  	struct vde_data *vpri;
17c324fa8   Wang Chen   um: Kill directly...
20
  	pri = netdev_priv(dev);
ad43c3565   Jeff Dike   uml: add VDE netw...
21
22
23
24
25
26
27
  	vpri = (struct vde_data *) pri->user;
  
  	vpri->vde_switch = init->vde_switch;
  	vpri->descr = init->descr ? init->descr : "UML vde_transport";
  	vpri->args = NULL;
  	vpri->conn = NULL;
  	vpri->dev = dev;
cd1ae0e49   Jeff Dike   uml: network form...
28
  	printk("vde backend - %s, ", vpri->vde_switch ?
ad43c3565   Jeff Dike   uml: add VDE netw...
29
30
31
  	       vpri->vde_switch : "(default socket)");
  
  	vde_init_libstuff(vpri, init);
cd1ae0e49   Jeff Dike   uml: network form...
32
33
  	printk("
  ");
ad43c3565   Jeff Dike   uml: add VDE netw...
34
  }
b53f35a80   Jeff Dike   uml: network driv...
35
  static int vde_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
ad43c3565   Jeff Dike   uml: add VDE netw...
36
37
  {
  	struct vde_data *pri = (struct vde_data *) &lp->user;
b53f35a80   Jeff Dike   uml: network driv...
38
39
40
  	if (pri->conn != NULL)
  		return vde_user_read(pri->conn, skb_mac_header(skb),
  				     skb->dev->mtu + ETH_HEADER_OTHER);
ad43c3565   Jeff Dike   uml: add VDE netw...
41
42
43
44
  
  	printk(KERN_ERR "vde_read - we have no VDECONN to read from");
  	return -EBADF;
  }
b53f35a80   Jeff Dike   uml: network driv...
45
  static int vde_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
ad43c3565   Jeff Dike   uml: add VDE netw...
46
47
48
49
  {
  	struct vde_data *pri = (struct vde_data *) &lp->user;
  
  	if (pri->conn != NULL)
b53f35a80   Jeff Dike   uml: network driv...
50
51
  		return vde_user_write((void *)pri->conn, skb->data,
  				      skb->len);
ad43c3565   Jeff Dike   uml: add VDE netw...
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  
  	printk(KERN_ERR "vde_write - we have no VDECONN to write to");
  	return -EBADF;
  }
  
  static const struct net_kern_info vde_kern_info = {
  	.init			= vde_init,
  	.protocol		= eth_protocol,
  	.read			= vde_read,
  	.write			= vde_write,
  };
  
  static int vde_setup(char *str, char **mac_out, void *data)
  {
  	struct vde_init *init = data;
  	char *remain, *port_str = NULL, *mode_str = NULL, *last;
  
  	*init = ((struct vde_init)
  		{ .vde_switch		= NULL,
  		  .descr		= NULL,
  		  .port			= 0,
  		  .group		= NULL,
  		  .mode			= 0 });
  
  	remain = split_if_spec(str, &init->vde_switch, mac_out, &port_str,
  				&init->group, &mode_str, &init->descr, NULL);
  
  	if (remain != NULL)
  		printk(KERN_WARNING "vde_setup - Ignoring extra data :"
  		       "'%s'
  ", remain);
  
  	if (port_str != NULL) {
  		init->port = simple_strtoul(port_str, &last, 10);
  		if ((*last != '\0') || (last == port_str)) {
  			printk(KERN_ERR "vde_setup - Bad port : '%s'
  ",
  						port_str);
  			return 0;
  		}
  	}
  
  	if (mode_str != NULL) {
  		init->mode = simple_strtoul(mode_str, &last, 8);
  		if ((*last != '\0') || (last == mode_str)) {
  			printk(KERN_ERR "vde_setup - Bad mode : '%s'
  ",
  						mode_str);
  			return 0;
  		}
  	}
  
  	printk(KERN_INFO "Configured vde device: %s
  ", init->vde_switch ?
  	       init->vde_switch : "(default socket)");
  
  	return 1;
  }
  
  static struct transport vde_transport = {
  	.list 		= LIST_HEAD_INIT(vde_transport.list),
  	.name 		= "vde",
  	.setup  	= vde_setup,
  	.user 		= &vde_user_info,
  	.kern 		= &vde_kern_info,
  	.private_size 	= sizeof(struct vde_data),
  	.setup_size 	= sizeof(struct vde_init),
  };
  
  static int register_vde(void)
  {
  	register_transport(&vde_transport);
  	return 0;
  }
  
  late_initcall(register_vde);