Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vector_user: add VDE support

This is the actual implementation of VDE support as a vector transport.

Signed-off-by: Renzo Davoli <renzo@cs.unibo.it>
Acked-By: Anton Ivanov <anton.ivanov@cambridgegreys.com>
Signed-off-by: Richard Weinberger <richard@nod.at>

authored by

Renzo Davoli and committed by
Richard Weinberger
ab1d5895 64dcf0b8

+83
+83
arch/um/drivers/vector_user.c
··· 46 46 #define TRANS_FD "fd" 47 47 #define TRANS_FD_LEN strlen(TRANS_FD) 48 48 49 + #define TRANS_VDE "vde" 50 + #define TRANS_VDE_LEN strlen(TRANS_VDE) 51 + 49 52 #define VNET_HDR_FAIL "could not enable vnet headers on fd %d" 50 53 #define TUN_GET_F_FAIL "tapraw: TUNGETFEATURES failed: %s" 51 54 #define L2TPV3_BIND_FAIL "l2tpv3_open : could not bind socket err=%i" ··· 437 434 return NULL; 438 435 } 439 436 437 + /* enough char to store an int type */ 438 + #define ENOUGH(type) ((CHAR_BIT * sizeof(type) - 1) / 3 + 2) 439 + #define ENOUGH_OCTAL(type) ((CHAR_BIT * sizeof(type) + 2) / 3) 440 + /* vde_plug --descr xx --port2 xx --mod2 xx --group2 xx seqpacket://NN vnl (NULL) */ 441 + #define VDE_MAX_ARGC 12 442 + #define VDE_SEQPACKET_HEAD "seqpacket://" 443 + #define VDE_SEQPACKET_HEAD_LEN (sizeof(VDE_SEQPACKET_HEAD) - 1) 444 + #define VDE_DEFAULT_DESCRIPTION "UML" 445 + 446 + static struct vector_fds *user_init_vde_fds(struct arglist *ifspec) 447 + { 448 + char seqpacketvnl[VDE_SEQPACKET_HEAD_LEN + ENOUGH(int) + 1]; 449 + char *argv[VDE_MAX_ARGC] = {"vde_plug"}; 450 + int argc = 1; 451 + int rv; 452 + int sv[2]; 453 + struct vector_fds *result = NULL; 454 + 455 + char *vnl = uml_vector_fetch_arg(ifspec,"vnl"); 456 + char *descr = uml_vector_fetch_arg(ifspec,"descr"); 457 + char *port = uml_vector_fetch_arg(ifspec,"port"); 458 + char *mode = uml_vector_fetch_arg(ifspec,"mode"); 459 + char *group = uml_vector_fetch_arg(ifspec,"group"); 460 + if (descr == NULL) descr = VDE_DEFAULT_DESCRIPTION; 461 + 462 + argv[argc++] = "--descr"; 463 + argv[argc++] = descr; 464 + if (port != NULL) { 465 + argv[argc++] = "--port2"; 466 + argv[argc++] = port; 467 + } 468 + if (mode != NULL) { 469 + argv[argc++] = "--mod2"; 470 + argv[argc++] = mode; 471 + } 472 + if (group != NULL) { 473 + argv[argc++] = "--group2"; 474 + argv[argc++] = group; 475 + } 476 + argv[argc++] = seqpacketvnl; 477 + argv[argc++] = vnl; 478 + argv[argc++] = NULL; 479 + 480 + rv = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sv); 481 + if (rv < 0) { 482 + printk(UM_KERN_ERR "vde: seqpacket socketpair err %d", -errno); 483 + return NULL; 484 + } 485 + rv = os_set_exec_close(sv[0]); 486 + if (rv < 0) { 487 + printk(UM_KERN_ERR "vde: seqpacket socketpair cloexec err %d", -errno); 488 + goto vde_cleanup_sv; 489 + } 490 + snprintf(seqpacketvnl, sizeof(seqpacketvnl), VDE_SEQPACKET_HEAD "%d", sv[1]); 491 + 492 + run_helper(NULL, NULL, argv); 493 + 494 + close(sv[1]); 495 + 496 + result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); 497 + if (result == NULL) { 498 + printk(UM_KERN_ERR "fd open: allocation failed"); 499 + goto vde_cleanup; 500 + } 501 + 502 + result->rx_fd = sv[0]; 503 + result->tx_fd = sv[0]; 504 + result->remote_addr_size = 0; 505 + result->remote_addr = NULL; 506 + return result; 507 + 508 + vde_cleanup_sv: 509 + close(sv[1]); 510 + vde_cleanup: 511 + close(sv[0]); 512 + return NULL; 513 + } 514 + 440 515 static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) 441 516 { 442 517 int rxfd = -1, txfd = -1; ··· 754 673 return user_init_unix_fds(parsed, ID_BESS); 755 674 if (strncmp(transport, TRANS_FD, TRANS_FD_LEN) == 0) 756 675 return user_init_fd_fds(parsed); 676 + if (strncmp(transport, TRANS_VDE, TRANS_VDE_LEN) == 0) 677 + return user_init_vde_fds(parsed); 757 678 return NULL; 758 679 } 759 680