diff options
author | Jeff Dike <jdike@addtoit.com> | 2007-10-16 04:26:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:05 -0400 |
commit | ad43c3565bebada7e5a13288e37542fd940369e8 (patch) | |
tree | 0946d7e5fc8f4bfa9ce5932d2cd1a921946e7c86 /arch/um/drivers/vde_user.c | |
parent | 6d536e4b59f77c34a0e5a414dfa934db373c85c2 (diff) |
uml: add VDE networking support
Added vde network backend in uml to introduce native Virtual Distributed
Ethernet support (using libvdeplug).
Signed-off-by: Luca Bigliardi <shammash@artha.org>
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um/drivers/vde_user.c')
-rw-r--r-- | arch/um/drivers/vde_user.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c new file mode 100644 index 000000000000..d3b5a065fc52 --- /dev/null +++ b/arch/um/drivers/vde_user.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org). | ||
3 | * Licensed under the GPL. | ||
4 | */ | ||
5 | |||
6 | #include <errno.h> | ||
7 | #include <unistd.h> | ||
8 | #include <libvdeplug.h> | ||
9 | #include "net_user.h" | ||
10 | #include "kern_util.h" | ||
11 | #include "kern_constants.h" | ||
12 | #include "user.h" | ||
13 | #include "os.h" | ||
14 | #include "um_malloc.h" | ||
15 | #include "vde.h" | ||
16 | |||
17 | #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) | ||
18 | |||
19 | static int vde_user_init(void *data, void *dev) | ||
20 | { | ||
21 | struct vde_data *pri = data; | ||
22 | VDECONN *conn = NULL; | ||
23 | int err = -EINVAL; | ||
24 | |||
25 | pri->dev = dev; | ||
26 | |||
27 | conn = vde_open(pri->vde_switch, pri->descr, pri->args); | ||
28 | |||
29 | if (conn == NULL) { | ||
30 | err = -errno; | ||
31 | printk(UM_KERN_ERR "vde_user_init: vde_open failed, " | ||
32 | "errno = %d\n", errno); | ||
33 | return err; | ||
34 | } | ||
35 | |||
36 | printk(UM_KERN_INFO "vde backend - connection opened\n"); | ||
37 | |||
38 | pri->conn = conn; | ||
39 | |||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static int vde_user_open(void *data) | ||
44 | { | ||
45 | struct vde_data *pri = data; | ||
46 | |||
47 | if (pri->conn != NULL) | ||
48 | return vde_datafd(pri->conn); | ||
49 | |||
50 | printk(UM_KERN_WARNING "vde_open - we have no VDECONN to open"); | ||
51 | return -EINVAL; | ||
52 | } | ||
53 | |||
54 | static void vde_remove(void *data) | ||
55 | { | ||
56 | struct vde_data *pri = data; | ||
57 | |||
58 | if (pri->conn != NULL) { | ||
59 | printk(UM_KERN_INFO "vde backend - closing connection\n"); | ||
60 | vde_close(pri->conn); | ||
61 | pri->conn = NULL; | ||
62 | kfree(pri->args); | ||
63 | pri->args = NULL; | ||
64 | return; | ||
65 | } | ||
66 | |||
67 | printk(UM_KERN_WARNING "vde_remove - we have no VDECONN to remove"); | ||
68 | } | ||
69 | |||
70 | static int vde_set_mtu(int mtu, void *data) | ||
71 | { | ||
72 | return mtu; | ||
73 | } | ||
74 | |||
75 | const struct net_user_info vde_user_info = { | ||
76 | .init = vde_user_init, | ||
77 | .open = vde_user_open, | ||
78 | .close = NULL, | ||
79 | .remove = vde_remove, | ||
80 | .set_mtu = vde_set_mtu, | ||
81 | .add_address = NULL, | ||
82 | .delete_address = NULL, | ||
83 | .max_packet = MAX_PACKET - ETH_HEADER_OTHER | ||
84 | }; | ||
85 | |||
86 | void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init) | ||
87 | { | ||
88 | struct vde_open_args *args; | ||
89 | |||
90 | vpri->args = kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL); | ||
91 | if (vpri->args == NULL) { | ||
92 | printk(UM_KERN_ERR "vde_init_libstuff - vde_open_args" | ||
93 | "allocation failed"); | ||
94 | return; | ||
95 | } | ||
96 | |||
97 | args = vpri->args; | ||
98 | |||
99 | args->port = init->port; | ||
100 | args->group = init->group; | ||
101 | args->mode = init->mode ? init->mode : 0700; | ||
102 | |||
103 | args->port ? printk(UM_KERN_INFO "port %d", args->port) : | ||
104 | printk(UM_KERN_INFO "undefined port"); | ||
105 | } | ||
106 | |||
107 | int vde_user_read(void *conn, void *buf, int len) | ||
108 | { | ||
109 | VDECONN *vconn = conn; | ||
110 | int rv; | ||
111 | |||
112 | if (vconn == NULL) | ||
113 | return 0; | ||
114 | |||
115 | rv = vde_recv(vconn, buf, len, 0); | ||
116 | if (rv < 0) { | ||
117 | if (errno == EAGAIN) | ||
118 | return 0; | ||
119 | return -errno; | ||
120 | } | ||
121 | else if (rv == 0) | ||
122 | return -ENOTCONN; | ||
123 | |||
124 | return rv; | ||
125 | } | ||
126 | |||
127 | int vde_user_write(void *conn, void *buf, int len) | ||
128 | { | ||
129 | VDECONN *vconn = conn; | ||
130 | |||
131 | if (vconn == NULL) | ||
132 | return 0; | ||
133 | |||
134 | return vde_send(vconn, buf, len, 0); | ||
135 | } | ||
136 | |||