diff options
Diffstat (limited to 'arch/um/os-Linux/drivers/ethertap_user.c')
-rw-r--r-- | arch/um/os-Linux/drivers/ethertap_user.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index 61d3953c7a..d74eedb7e6 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c | |||
@@ -87,11 +87,11 @@ static void etap_pre_exec(void *arg) | |||
87 | struct etap_pre_exec_data *data = arg; | 87 | struct etap_pre_exec_data *data = arg; |
88 | 88 | ||
89 | dup2(data->control_remote, 1); | 89 | dup2(data->control_remote, 1); |
90 | os_close_file(data->data_me); | 90 | close(data->data_me); |
91 | os_close_file(data->control_me); | 91 | close(data->control_me); |
92 | } | 92 | } |
93 | 93 | ||
94 | static int etap_tramp(char *dev, char *gate, int control_me, | 94 | static int etap_tramp(char *dev, char *gate, int control_me, |
95 | int control_remote, int data_me, int data_remote) | 95 | int control_remote, int data_me, int data_remote) |
96 | { | 96 | { |
97 | struct etap_pre_exec_data pe_data; | 97 | struct etap_pre_exec_data pe_data; |
@@ -101,7 +101,7 @@ static int etap_tramp(char *dev, char *gate, int control_me, | |||
101 | char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; | 101 | char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; |
102 | char *setup_args[] = { "uml_net", version_buf, "ethertap", dev, | 102 | char *setup_args[] = { "uml_net", version_buf, "ethertap", dev, |
103 | data_fd_buf, gate_buf, NULL }; | 103 | data_fd_buf, gate_buf, NULL }; |
104 | char *nosetup_args[] = { "uml_net", version_buf, "ethertap", | 104 | char *nosetup_args[] = { "uml_net", version_buf, "ethertap", |
105 | dev, data_fd_buf, NULL }; | 105 | dev, data_fd_buf, NULL }; |
106 | char **args, c; | 106 | char **args, c; |
107 | 107 | ||
@@ -121,8 +121,8 @@ static int etap_tramp(char *dev, char *gate, int control_me, | |||
121 | 121 | ||
122 | if(pid < 0) | 122 | if(pid < 0) |
123 | err = pid; | 123 | err = pid; |
124 | os_close_file(data_remote); | 124 | close(data_remote); |
125 | os_close_file(control_remote); | 125 | close(control_remote); |
126 | CATCH_EINTR(n = read(control_me, &c, sizeof(c))); | 126 | CATCH_EINTR(n = read(control_me, &c, sizeof(c))); |
127 | if(n != sizeof(c)){ | 127 | if(n != sizeof(c)){ |
128 | err = -errno; | 128 | err = -errno; |
@@ -151,19 +151,23 @@ static int etap_open(void *data) | |||
151 | if(err) | 151 | if(err) |
152 | return err; | 152 | return err; |
153 | 153 | ||
154 | err = os_pipe(data_fds, 0, 0); | 154 | err = socketpair(AF_UNIX, SOCK_DGRAM, 0, data_fds); |
155 | if(err < 0){ | 155 | if(err){ |
156 | printk("data os_pipe failed - err = %d\n", -err); | 156 | err = -errno; |
157 | printk("etap_open - data socketpair failed - err = %d\n", | ||
158 | errno); | ||
157 | return err; | 159 | return err; |
158 | } | 160 | } |
159 | 161 | ||
160 | err = os_pipe(control_fds, 1, 0); | 162 | err = socketpair(AF_UNIX, SOCK_STREAM, 0, control_fds); |
161 | if(err < 0){ | 163 | if(err){ |
162 | printk("control os_pipe failed - err = %d\n", -err); | 164 | err = -errno; |
163 | return err; | 165 | printk("etap_open - control socketpair failed - err = %d\n", |
166 | errno); | ||
167 | goto out_close_data; | ||
164 | } | 168 | } |
165 | 169 | ||
166 | err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], | 170 | err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], |
167 | control_fds[1], data_fds[0], data_fds[1]); | 171 | control_fds[1], data_fds[0], data_fds[1]); |
168 | output_len = UM_KERN_PAGE_SIZE; | 172 | output_len = UM_KERN_PAGE_SIZE; |
169 | output = kmalloc(output_len, UM_GFP_KERNEL); | 173 | output = kmalloc(output_len, UM_GFP_KERNEL); |
@@ -178,13 +182,21 @@ static int etap_open(void *data) | |||
178 | 182 | ||
179 | if(err < 0){ | 183 | if(err < 0){ |
180 | printk("etap_tramp failed - err = %d\n", -err); | 184 | printk("etap_tramp failed - err = %d\n", -err); |
181 | return err; | 185 | goto out_close_control; |
182 | } | 186 | } |
183 | 187 | ||
184 | pri->data_fd = data_fds[0]; | 188 | pri->data_fd = data_fds[0]; |
185 | pri->control_fd = control_fds[0]; | 189 | pri->control_fd = control_fds[0]; |
186 | iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); | 190 | iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); |
187 | return data_fds[0]; | 191 | return data_fds[0]; |
192 | |||
193 | out_close_control: | ||
194 | close(control_fds[0]); | ||
195 | close(control_fds[1]); | ||
196 | out_close_data: | ||
197 | close(data_fds[0]); | ||
198 | close(data_fds[1]); | ||
199 | return err; | ||
188 | } | 200 | } |
189 | 201 | ||
190 | static void etap_close(int fd, void *data) | 202 | static void etap_close(int fd, void *data) |
@@ -192,11 +204,19 @@ static void etap_close(int fd, void *data) | |||
192 | struct ethertap_data *pri = data; | 204 | struct ethertap_data *pri = data; |
193 | 205 | ||
194 | iter_addresses(pri->dev, etap_close_addr, &pri->control_fd); | 206 | iter_addresses(pri->dev, etap_close_addr, &pri->control_fd); |
195 | os_close_file(fd); | 207 | close(fd); |
196 | os_shutdown_socket(pri->data_fd, 1, 1); | 208 | |
197 | os_close_file(pri->data_fd); | 209 | if(shutdown(pri->data_fd, SHUT_RDWR) < 0) |
210 | printk("etap_close - shutdown data socket failed, errno = %d\n", | ||
211 | errno); | ||
212 | |||
213 | if(shutdown(pri->control_fd, SHUT_RDWR) < 0) | ||
214 | printk("etap_close - shutdown control socket failed, " | ||
215 | "errno = %d\n", errno); | ||
216 | |||
217 | close(pri->data_fd); | ||
198 | pri->data_fd = -1; | 218 | pri->data_fd = -1; |
199 | os_close_file(pri->control_fd); | 219 | close(pri->control_fd); |
200 | pri->control_fd = -1; | 220 | pri->control_fd = -1; |
201 | } | 221 | } |
202 | 222 | ||
@@ -216,13 +236,14 @@ static void etap_add_addr(unsigned char *addr, unsigned char *netmask, | |||
216 | etap_open_addr(addr, netmask, &pri->control_fd); | 236 | etap_open_addr(addr, netmask, &pri->control_fd); |
217 | } | 237 | } |
218 | 238 | ||
219 | static void etap_del_addr(unsigned char *addr, unsigned char *netmask, | 239 | static void etap_del_addr(unsigned char *addr, unsigned char *netmask, |
220 | void *data) | 240 | void *data) |
221 | { | 241 | { |
222 | struct ethertap_data *pri = data; | 242 | struct ethertap_data *pri = data; |
223 | 243 | ||
224 | if(pri->control_fd == -1) | 244 | if(pri->control_fd == -1) |
225 | return; | 245 | return; |
246 | |||
226 | etap_close_addr(addr, netmask, &pri->control_fd); | 247 | etap_close_addr(addr, netmask, &pri->control_fd); |
227 | } | 248 | } |
228 | 249 | ||