0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <stdio.h>
0010 #include <unistd.h>
0011 #include <errno.h>
0012 #include <string.h>
0013 #include <sys/socket.h>
0014 #include <sys/wait.h>
0015 #include "etap.h"
0016 #include <os.h>
0017 #include <net_user.h>
0018 #include <um_malloc.h>
0019
0020 #define MAX_PACKET ETH_MAX_PACKET
0021
0022 static int etap_user_init(void *data, void *dev)
0023 {
0024 struct ethertap_data *pri = data;
0025
0026 pri->dev = dev;
0027 return 0;
0028 }
0029
0030 struct addr_change {
0031 enum { ADD_ADDR, DEL_ADDR } what;
0032 unsigned char addr[4];
0033 unsigned char netmask[4];
0034 };
0035
0036 static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
0037 int fd)
0038 {
0039 struct addr_change change;
0040 char *output;
0041 int n;
0042
0043 change.what = op;
0044 memcpy(change.addr, addr, sizeof(change.addr));
0045 memcpy(change.netmask, netmask, sizeof(change.netmask));
0046 CATCH_EINTR(n = write(fd, &change, sizeof(change)));
0047 if (n != sizeof(change)) {
0048 printk(UM_KERN_ERR "etap_change - request failed, err = %d\n",
0049 errno);
0050 return;
0051 }
0052
0053 output = uml_kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
0054 if (output == NULL)
0055 printk(UM_KERN_ERR "etap_change : Failed to allocate output "
0056 "buffer\n");
0057 read_output(fd, output, UM_KERN_PAGE_SIZE);
0058 if (output != NULL) {
0059 printk("%s", output);
0060 kfree(output);
0061 }
0062 }
0063
0064 static void etap_open_addr(unsigned char *addr, unsigned char *netmask,
0065 void *arg)
0066 {
0067 etap_change(ADD_ADDR, addr, netmask, *((int *) arg));
0068 }
0069
0070 static void etap_close_addr(unsigned char *addr, unsigned char *netmask,
0071 void *arg)
0072 {
0073 etap_change(DEL_ADDR, addr, netmask, *((int *) arg));
0074 }
0075
0076 struct etap_pre_exec_data {
0077 int control_remote;
0078 int control_me;
0079 int data_me;
0080 };
0081
0082 static void etap_pre_exec(void *arg)
0083 {
0084 struct etap_pre_exec_data *data = arg;
0085
0086 dup2(data->control_remote, 1);
0087 close(data->data_me);
0088 close(data->control_me);
0089 }
0090
0091 static int etap_tramp(char *dev, char *gate, int control_me,
0092 int control_remote, int data_me, int data_remote)
0093 {
0094 struct etap_pre_exec_data pe_data;
0095 int pid, err, n;
0096 char version_buf[sizeof("nnnnn\0")];
0097 char data_fd_buf[sizeof("nnnnnn\0")];
0098 char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
0099 char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
0100 data_fd_buf, gate_buf, NULL };
0101 char *nosetup_args[] = { "uml_net", version_buf, "ethertap",
0102 dev, data_fd_buf, NULL };
0103 char **args, c;
0104
0105 sprintf(data_fd_buf, "%d", data_remote);
0106 sprintf(version_buf, "%d", UML_NET_VERSION);
0107 if (gate != NULL) {
0108 strncpy(gate_buf, gate, 15);
0109 args = setup_args;
0110 }
0111 else args = nosetup_args;
0112
0113 err = 0;
0114 pe_data.control_remote = control_remote;
0115 pe_data.control_me = control_me;
0116 pe_data.data_me = data_me;
0117 pid = run_helper(etap_pre_exec, &pe_data, args);
0118
0119 if (pid < 0)
0120 err = pid;
0121 close(data_remote);
0122 close(control_remote);
0123 CATCH_EINTR(n = read(control_me, &c, sizeof(c)));
0124 if (n != sizeof(c)) {
0125 err = -errno;
0126 printk(UM_KERN_ERR "etap_tramp : read of status failed, "
0127 "err = %d\n", -err);
0128 return err;
0129 }
0130 if (c != 1) {
0131 printk(UM_KERN_ERR "etap_tramp : uml_net failed\n");
0132 err = helper_wait(pid);
0133 }
0134 return err;
0135 }
0136
0137 static int etap_open(void *data)
0138 {
0139 struct ethertap_data *pri = data;
0140 char *output;
0141 int data_fds[2], control_fds[2], err, output_len;
0142
0143 err = tap_open_common(pri->dev, pri->gate_addr);
0144 if (err)
0145 return err;
0146
0147 err = socketpair(AF_UNIX, SOCK_DGRAM, 0, data_fds);
0148 if (err) {
0149 err = -errno;
0150 printk(UM_KERN_ERR "etap_open - data socketpair failed - "
0151 "err = %d\n", errno);
0152 return err;
0153 }
0154
0155 err = socketpair(AF_UNIX, SOCK_STREAM, 0, control_fds);
0156 if (err) {
0157 err = -errno;
0158 printk(UM_KERN_ERR "etap_open - control socketpair failed - "
0159 "err = %d\n", errno);
0160 goto out_close_data;
0161 }
0162
0163 err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
0164 control_fds[1], data_fds[0], data_fds[1]);
0165 output_len = UM_KERN_PAGE_SIZE;
0166 output = uml_kmalloc(output_len, UM_GFP_KERNEL);
0167 read_output(control_fds[0], output, output_len);
0168
0169 if (output == NULL)
0170 printk(UM_KERN_ERR "etap_open : failed to allocate output "
0171 "buffer\n");
0172 else {
0173 printk("%s", output);
0174 kfree(output);
0175 }
0176
0177 if (err < 0) {
0178 printk(UM_KERN_ERR "etap_tramp failed - err = %d\n", -err);
0179 goto out_close_control;
0180 }
0181
0182 pri->data_fd = data_fds[0];
0183 pri->control_fd = control_fds[0];
0184 iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
0185 return data_fds[0];
0186
0187 out_close_control:
0188 close(control_fds[0]);
0189 close(control_fds[1]);
0190 out_close_data:
0191 close(data_fds[0]);
0192 close(data_fds[1]);
0193 return err;
0194 }
0195
0196 static void etap_close(int fd, void *data)
0197 {
0198 struct ethertap_data *pri = data;
0199
0200 iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
0201 close(fd);
0202
0203 if (shutdown(pri->data_fd, SHUT_RDWR) < 0)
0204 printk(UM_KERN_ERR "etap_close - shutdown data socket failed, "
0205 "errno = %d\n", errno);
0206
0207 if (shutdown(pri->control_fd, SHUT_RDWR) < 0)
0208 printk(UM_KERN_ERR "etap_close - shutdown control socket "
0209 "failed, errno = %d\n", errno);
0210
0211 close(pri->data_fd);
0212 pri->data_fd = -1;
0213 close(pri->control_fd);
0214 pri->control_fd = -1;
0215 }
0216
0217 static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
0218 void *data)
0219 {
0220 struct ethertap_data *pri = data;
0221
0222 tap_check_ips(pri->gate_addr, addr);
0223 if (pri->control_fd == -1)
0224 return;
0225 etap_open_addr(addr, netmask, &pri->control_fd);
0226 }
0227
0228 static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
0229 void *data)
0230 {
0231 struct ethertap_data *pri = data;
0232
0233 if (pri->control_fd == -1)
0234 return;
0235
0236 etap_close_addr(addr, netmask, &pri->control_fd);
0237 }
0238
0239 const struct net_user_info ethertap_user_info = {
0240 .init = etap_user_init,
0241 .open = etap_open,
0242 .close = etap_close,
0243 .remove = NULL,
0244 .add_address = etap_add_addr,
0245 .delete_address = etap_del_addr,
0246 .mtu = ETH_MAX_PACKET,
0247 .max_packet = ETH_MAX_PACKET + ETH_HEADER_ETHERTAP,
0248 };