|
29 | 29 | #include <netdb.h>
|
30 | 30 | #include <stdlib.h>
|
31 | 31 | #include <os.h>
|
| 32 | +#include <limits.h> |
32 | 33 | #include <um_malloc.h>
|
33 | 34 | #include "vector_user.h"
|
34 | 35 |
|
|
42 | 43 | #define TRANS_RAW "raw"
|
43 | 44 | #define TRANS_RAW_LEN strlen(TRANS_RAW)
|
44 | 45 |
|
| 46 | +#define TRANS_FD "fd" |
| 47 | +#define TRANS_FD_LEN strlen(TRANS_FD) |
| 48 | + |
45 | 49 | #define VNET_HDR_FAIL "could not enable vnet headers on fd %d"
|
46 | 50 | #define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s"
|
47 | 51 | #define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i"
|
@@ -347,6 +351,59 @@ static struct vector_fds *user_init_unix_fds(struct arglist *ifspec, int id)
|
347 | 351 | return NULL;
|
348 | 352 | }
|
349 | 353 |
|
| 354 | +static int strtofd(const char *nptr) |
| 355 | +{ |
| 356 | + long fd; |
| 357 | + char *endptr; |
| 358 | + |
| 359 | + if (nptr == NULL) |
| 360 | + return -1; |
| 361 | + |
| 362 | + errno = 0; |
| 363 | + fd = strtol(nptr, &endptr, 10); |
| 364 | + if (nptr == endptr || |
| 365 | + errno != 0 || |
| 366 | + *endptr != '\0' || |
| 367 | + fd < 0 || |
| 368 | + fd > INT_MAX) { |
| 369 | + return -1; |
| 370 | + } |
| 371 | + return fd; |
| 372 | +} |
| 373 | + |
| 374 | +static struct vector_fds *user_init_fd_fds(struct arglist *ifspec) |
| 375 | +{ |
| 376 | + int fd = -1; |
| 377 | + char *fdarg = NULL; |
| 378 | + struct vector_fds *result = NULL; |
| 379 | + |
| 380 | + fdarg = uml_vector_fetch_arg(ifspec, "fd"); |
| 381 | + fd = strtofd(fdarg); |
| 382 | + if (fd == -1) { |
| 383 | + printk(UM_KERN_ERR "fd open: bad or missing fd argument"); |
| 384 | + goto fd_cleanup; |
| 385 | + } |
| 386 | + |
| 387 | + result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); |
| 388 | + if (result == NULL) { |
| 389 | + printk(UM_KERN_ERR "fd open: allocation failed"); |
| 390 | + goto fd_cleanup; |
| 391 | + } |
| 392 | + |
| 393 | + result->rx_fd = fd; |
| 394 | + result->tx_fd = fd; |
| 395 | + result->remote_addr_size = 0; |
| 396 | + result->remote_addr = NULL; |
| 397 | + return result; |
| 398 | + |
| 399 | +fd_cleanup: |
| 400 | + if (fd >= 0) |
| 401 | + os_close_file(fd); |
| 402 | + if (result != NULL) |
| 403 | + kfree(result); |
| 404 | + return NULL; |
| 405 | +} |
| 406 | + |
350 | 407 | static struct vector_fds *user_init_raw_fds(struct arglist *ifspec)
|
351 | 408 | {
|
352 | 409 | int rxfd = -1, txfd = -1;
|
@@ -578,6 +635,8 @@ struct vector_fds *uml_vector_user_open(
|
578 | 635 | return user_init_socket_fds(parsed, ID_L2TPV3);
|
579 | 636 | if (strncmp(transport, TRANS_BESS, TRANS_BESS_LEN) == 0)
|
580 | 637 | return user_init_unix_fds(parsed, ID_BESS);
|
| 638 | + if (strncmp(transport, TRANS_FD, TRANS_FD_LEN) == 0) |
| 639 | + return user_init_fd_fds(parsed); |
581 | 640 | return NULL;
|
582 | 641 | }
|
583 | 642 |
|
|
0 commit comments