Skip to content

Commit f06885b

Browse files
kot-begemot-ukrichardweinberger
authored andcommitted
um: vector: Add dynamic tap interfaces and scripting
Provide functionality roughly compatible with the existing qemu ifup scripting: * invocation of an ifup script. The interface name is passed as the first and only argument * allocating tap interfaces on the fly if they are not explicitly specified Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com> Signed-off-by: Richard Weinberger <richard@nod.at>
1 parent 273fe1b commit f06885b

1 file changed

Lines changed: 47 additions & 9 deletions

File tree

arch/um/drivers/vector_user.c

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#define ID_MAX 2
3838

3939
#define TOKEN_IFNAME "ifname"
40+
#define TOKEN_SCRIPT "ifup"
4041

4142
#define TRANS_RAW "raw"
4243
#define TRANS_RAW_LEN strlen(TRANS_RAW)
@@ -53,6 +54,9 @@
5354

5455
#define MAX_UN_LEN 107
5556

57+
static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
58+
static const char *template = "tapXXXXXX";
59+
5660
/* This is very ugly and brute force lookup, but it is done
5761
* only once at initialization so not worth doing hashes or
5862
* anything more intelligent
@@ -189,16 +193,21 @@ static int create_raw_fd(char *iface, int flags, int proto)
189193
return err;
190194
}
191195

196+
192197
static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
193198
{
194-
int fd = -1;
199+
int fd = -1, i;
195200
char *iface;
196201
struct vector_fds *result = NULL;
202+
bool dynamic = false;
203+
char dynamic_ifname[IFNAMSIZ];
204+
char *argv[] = {NULL, NULL, NULL, NULL};
197205

198206
iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
199207
if (iface == NULL) {
200-
printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n");
201-
goto tap_cleanup;
208+
dynamic = true;
209+
iface = dynamic_ifname;
210+
srand(getpid());
202211
}
203212

204213
result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL);
@@ -212,14 +221,30 @@ static struct vector_fds *user_init_tap_fds(struct arglist *ifspec)
212221
result->remote_addr_size = 0;
213222

214223
/* TAP */
224+
do {
225+
if (dynamic) {
226+
strcpy(iface, template);
227+
for (i = 0; i < strlen(iface); i++) {
228+
if (iface[i] == 'X') {
229+
iface[i] = padchar[rand() % strlen(padchar)];
230+
}
231+
}
232+
}
233+
fd = create_tap_fd(iface);
234+
if ((fd < 0) && (!dynamic)) {
235+
printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n");
236+
goto tap_cleanup;
237+
}
238+
result->tx_fd = fd;
239+
result->rx_fd = fd;
240+
} while (fd < 0);
215241

216-
fd = create_tap_fd(iface);
217-
if (fd < 0) {
218-
printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n");
219-
goto tap_cleanup;
242+
argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
243+
if (argv[0]) {
244+
argv[1] = iface;
245+
run_helper(NULL, NULL, argv);
220246
}
221-
result->tx_fd = fd;
222-
result->rx_fd = fd;
247+
223248
return result;
224249
tap_cleanup:
225250
printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd);
@@ -231,6 +256,7 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
231256
{
232257
char *iface;
233258
struct vector_fds *result = NULL;
259+
char *argv[] = {NULL, NULL, NULL, NULL};
234260

235261
iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
236262
if (iface == NULL) {
@@ -264,6 +290,12 @@ static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec)
264290
"uml_tap: failed to create paired raw socket: %i\n", result->rx_fd);
265291
goto hybrid_cleanup;
266292
}
293+
294+
argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
295+
if (argv[0]) {
296+
argv[1] = iface;
297+
run_helper(NULL, NULL, argv);
298+
}
267299
return result;
268300
hybrid_cleanup:
269301
printk(UM_KERN_ERR "user_init_hybrid: init failed");
@@ -407,6 +439,7 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
407439
int err = -ENOMEM;
408440
char *iface;
409441
struct vector_fds *result = NULL;
442+
char *argv[] = {NULL, NULL, NULL, NULL};
410443

411444
iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME);
412445
if (iface == NULL)
@@ -429,6 +462,11 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
429462
result->remote_addr = NULL;
430463
result->remote_addr_size = 0;
431464
}
465+
argv[0] = uml_vector_fetch_arg(ifspec, TOKEN_SCRIPT);
466+
if (argv[0]) {
467+
argv[1] = iface;
468+
run_helper(NULL, NULL, argv);
469+
}
432470
return result;
433471
raw_cleanup:
434472
printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err);

0 commit comments

Comments
 (0)