uml: add VDE networking support
[safe/jmp/linux-2.6] / arch / um / drivers / vde_user.c
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