Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
um
drivers
daemon_user.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3
* Copyright (C) 2001 Lennert Buytenhek (
[email protected]
) and
4
* James Leu (
[email protected]
).
5
* Copyright (C) 2001 by various other people who didn't put their name here.
6
* Licensed under the GPL.
7
*/
8
9
#include <stdint.h>
10
#include <unistd.h>
11
#include <errno.h>
12
#include <sys/types.h>
13
#include <sys/socket.h>
14
#include <sys/time.h>
15
#include <sys/un.h>
16
#include "
daemon.h
"
17
#include <
net_user.h
>
18
#include <os.h>
19
#include <
um_malloc.h
>
20
21
enum
request_type
{
REQ_NEW_CONTROL
};
22
23
#define SWITCH_MAGIC 0xfeedface
24
25
struct
request_v3
{
26
uint32_t
magic
;
27
uint32_t
version
;
28
enum
request_type
type
;
29
struct
sockaddr_un
sock
;
30
};
31
32
static
struct
sockaddr_un
*new_addr(
void
*
name
,
int
len)
33
{
34
struct
sockaddr_un
*sun;
35
36
sun =
uml_kmalloc
(
sizeof
(
struct
sockaddr_un
), UM_GFP_KERNEL);
37
if
(sun ==
NULL
) {
38
printk
(
UM_KERN_ERR
"new_addr: allocation of sockaddr_un "
39
"failed\n"
);
40
return
NULL
;
41
}
42
sun->
sun_family
=
AF_UNIX
;
43
memcpy
(sun->
sun_path
, name, len);
44
return
sun;
45
}
46
47
static
int
connect_to_switch(
struct
daemon_data
*
pri
)
48
{
49
struct
sockaddr_un
*ctl_addr = pri->
ctl_addr
;
50
struct
sockaddr_un
*
local_addr
= pri->
local_addr
;
51
struct
sockaddr_un
*sun;
52
struct
request_v3
req
;
53
int
fd
,
n
,
err
;
54
55
pri->
control
=
socket
(
AF_UNIX
,
SOCK_STREAM
, 0);
56
if
(pri->
control
< 0) {
57
err = -
errno
;
58
printk
(
UM_KERN_ERR
"daemon_open : control socket failed, "
59
"errno = %d\n"
, -err);
60
return
err
;
61
}
62
63
if
(connect(pri->
control
, (
struct
sockaddr
*) ctl_addr,
64
sizeof
(*ctl_addr)) < 0) {
65
err = -
errno
;
66
printk
(
UM_KERN_ERR
"daemon_open : control connect failed, "
67
"errno = %d\n"
, -err);
68
goto
out
;
69
}
70
71
fd =
socket
(
AF_UNIX
,
SOCK_DGRAM
, 0);
72
if
(fd < 0) {
73
err = -
errno
;
74
printk
(
UM_KERN_ERR
"daemon_open : data socket failed, "
75
"errno = %d\n"
, -err);
76
goto
out
;
77
}
78
if
(bind(fd, (
struct
sockaddr
*) local_addr,
sizeof
(*local_addr)) < 0) {
79
err = -
errno
;
80
printk
(
UM_KERN_ERR
"daemon_open : data bind failed, "
81
"errno = %d\n"
, -err);
82
goto
out_close;
83
}
84
85
sun =
uml_kmalloc
(
sizeof
(
struct
sockaddr_un
), UM_GFP_KERNEL);
86
if
(sun ==
NULL
) {
87
printk
(
UM_KERN_ERR
"new_addr: allocation of sockaddr_un "
88
"failed\n"
);
89
err = -
ENOMEM
;
90
goto
out_close;
91
}
92
93
req
.magic =
SWITCH_MAGIC
;
94
req
.version =
SWITCH_VERSION
;
95
req
.type =
REQ_NEW_CONTROL
;
96
req
.sock = *
local_addr
;
97
n =
write
(pri->
control
, &
req
,
sizeof
(
req
));
98
if
(n !=
sizeof
(
req
)) {
99
printk
(
UM_KERN_ERR
"daemon_open : control setup request "
100
"failed, err = %d\n"
, -errno);
101
err = -
ENOTCONN
;
102
goto
out_free;
103
}
104
105
n =
read
(pri->
control
, sun,
sizeof
(*sun));
106
if
(n !=
sizeof
(*sun)) {
107
printk
(
UM_KERN_ERR
"daemon_open : read of data socket failed, "
108
"err = %d\n"
, -errno);
109
err = -
ENOTCONN
;
110
goto
out_free;
111
}
112
113
pri->
data_addr
= sun;
114
return
fd
;
115
116
out_free:
117
kfree
(sun);
118
out_close:
119
close(fd);
120
out
:
121
close(pri->
control
);
122
return
err
;
123
}
124
125
static
int
daemon_user_init(
void
*
data
,
void
*
dev
)
126
{
127
struct
daemon_data
*pri =
data
;
128
struct
timeval
tv;
129
struct
{
130
char
zero
;
131
int
pid
;
132
int
usecs
;
133
}
name
;
134
135
if
(!
strcmp
(pri->
sock_type
,
"unix"
))
136
pri->
ctl_addr
= new_addr(pri->
ctl_sock
,
137
strlen
(pri->
ctl_sock
) + 1);
138
name.zero = 0;
139
name.pid =
os_getpid
();
140
gettimeofday
(&tv,
NULL
);
141
name.usecs = tv.tv_usec;
142
pri->
local_addr
= new_addr(&name,
sizeof
(name));
143
pri->
dev
=
dev
;
144
pri->
fd
= connect_to_switch(pri);
145
if
(pri->
fd
< 0) {
146
kfree
(pri->
local_addr
);
147
pri->
local_addr
=
NULL
;
148
return
pri->
fd
;
149
}
150
151
return
0;
152
}
153
154
static
int
daemon_open(
void
*data)
155
{
156
struct
daemon_data
*pri =
data
;
157
return
pri->
fd
;
158
}
159
160
static
void
daemon_remove(
void
*data)
161
{
162
struct
daemon_data
*pri =
data
;
163
164
close(pri->
fd
);
165
pri->
fd
= -1;
166
close(pri->
control
);
167
pri->
control
= -1;
168
169
kfree
(pri->
data_addr
);
170
pri->
data_addr
=
NULL
;
171
kfree
(pri->
ctl_addr
);
172
pri->
ctl_addr
=
NULL
;
173
kfree
(pri->
local_addr
);
174
pri->
local_addr
=
NULL
;
175
}
176
177
int
daemon_user_write
(
int
fd,
void
*
buf
,
int
len,
struct
daemon_data
*pri)
178
{
179
struct
sockaddr_un
*
data_addr
= pri->
data_addr
;
180
181
return
net_sendto
(fd, buf, len, data_addr,
sizeof
(*data_addr));
182
}
183
184
const
struct
net_user_info
daemon_user_info
= {
185
.init = daemon_user_init,
186
.open = daemon_open,
187
.close =
NULL
,
188
.remove = daemon_remove,
189
.add_address =
NULL
,
190
.delete_address =
NULL
,
191
.mtu =
ETH_MAX_PACKET
,
192
.max_packet =
ETH_MAX_PACKET
+
ETH_HEADER_OTHER
,
193
};
Generated on Thu Jan 10 2013 13:19:15 for Linux Kernel by
1.8.2