Loading arch/um/drivers/vector_kern.c +2 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,8 @@ static int get_transport_options(struct arglist *def) if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0) return 0; if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0) return (vec_rx | VECTOR_BPF); if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0) return (vec_rx | vec_tx | VECTOR_QDISC_BYPASS); Loading arch/um/drivers/vector_transports.c +27 −2 Original line number Diff line number Diff line Loading @@ -418,7 +418,7 @@ static int build_raw_transport_data(struct vector_private *vp) return 0; } static int build_tap_transport_data(struct vector_private *vp) static int build_hybrid_transport_data(struct vector_private *vp) { if (uml_raw_enable_vnet_headers(vp->fds->rx_fd)) { vp->form_header = &raw_form_header; Loading @@ -432,7 +432,7 @@ static int build_tap_transport_data(struct vector_private *vp) NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); netdev_info( vp->dev, "tap/raw: using vnet headers for tso and tx/rx checksum" "tap/raw hybrid: using vnet headers for tso and tx/rx checksum" ); } else { return 0; /* do not try to enable tap too if raw failed */ Loading @@ -442,6 +442,29 @@ static int build_tap_transport_data(struct vector_private *vp) return -1; } static int build_tap_transport_data(struct vector_private *vp) { /* "Pure" tap uses the same fd for rx and tx */ if (uml_tap_enable_vnet_headers(vp->fds->tx_fd)) { vp->form_header = &raw_form_header; vp->verify_header = &raw_verify_header; vp->header_size = sizeof(struct virtio_net_hdr); vp->rx_header_size = sizeof(struct virtio_net_hdr); vp->dev->hw_features |= (NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); vp->dev->features |= (NETIF_F_RXCSUM | NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); netdev_info( vp->dev, "tap: using vnet headers for tso and tx/rx checksum" ); return 0; } return -1; } int build_transport_data(struct vector_private *vp) { char *transport = uml_vector_fetch_arg(vp->parsed, "transport"); Loading @@ -454,6 +477,8 @@ int build_transport_data(struct vector_private *vp) return build_raw_transport_data(vp); if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0) return build_tap_transport_data(vp); if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0) return build_hybrid_transport_data(vp); return 0; } arch/um/drivers/vector_user.c +119 −84 Original line number Diff line number Diff line Loading @@ -114,12 +114,76 @@ struct arglist *uml_parse_vector_ifspec(char *arg) #define PATH_NET_TUN "/dev/net/tun" static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) static int create_tap_fd(char *iface) { struct ifreq ifr; int fd = -1; struct sockaddr_ll sock; int err = -ENOMEM, offload; fd = open(PATH_NET_TUN, O_RDWR); if (fd < 0) { printk(UM_KERN_ERR "uml_tap: failed to open tun device\n"); goto tap_fd_cleanup; } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR; strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); err = ioctl(fd, TUNSETIFF, (void *) &ifr); if (err != 0) { printk(UM_KERN_ERR "uml_tap: failed to select tap interface\n"); goto tap_fd_cleanup; } offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6; ioctl(fd, TUNSETOFFLOAD, offload); return fd; tap_fd_cleanup: if (fd >= 0) os_close_file(fd); return err; } static int create_raw_fd(char *iface, int flags, int proto) { struct ifreq ifr; int fd = -1; struct sockaddr_ll sock; int err = -ENOMEM; fd = socket(AF_PACKET, SOCK_RAW, flags); if (fd == -1) { err = -errno; goto raw_fd_cleanup; } memset(&ifr, 0, sizeof(ifr)); strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) { err = -errno; goto raw_fd_cleanup; } sock.sll_family = AF_PACKET; sock.sll_protocol = htons(proto); sock.sll_ifindex = ifr.ifr_ifindex; if (bind(fd, (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { err = -errno; goto raw_fd_cleanup; } return fd; raw_fd_cleanup: printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err); if (fd >= 0) os_close_file(fd); return err; } static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) { int fd = -1; char *iface; struct vector_fds *result = NULL; Loading @@ -141,117 +205,88 @@ static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) /* TAP */ fd = open(PATH_NET_TUN, O_RDWR); fd = create_tap_fd(iface); if (fd < 0) { printk(UM_KERN_ERR "uml_tap: failed to open tun device\n"); printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n"); goto tap_cleanup; } result->tx_fd = fd; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR; strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); err = ioctl(fd, TUNSETIFF, (void *) &ifr); if (err != 0) { printk(UM_KERN_ERR "uml_tap: failed to select tap interface\n"); goto tap_cleanup; result->rx_fd = fd; return result; tap_cleanup: printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd); if (result != NULL) kfree(result); return NULL; } offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6; ioctl(fd, TUNSETOFFLOAD, offload); static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec) { char *iface; struct vector_fds *result = NULL; /* RAW */ iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); if (iface == NULL) { printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n"); goto hybrid_cleanup; } fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (fd == -1) { printk(UM_KERN_ERR "uml_tap: failed to create socket: %i\n", -errno); goto tap_cleanup; result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); if (result == NULL) { printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n"); goto hybrid_cleanup; } result->rx_fd = fd; memset(&ifr, 0, sizeof(ifr)); strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) { printk(UM_KERN_ERR "uml_tap: failed to set interface: %i\n", -errno); goto tap_cleanup; result->rx_fd = -1; result->tx_fd = -1; result->remote_addr = NULL; result->remote_addr_size = 0; /* TAP */ result->tx_fd = create_tap_fd(iface); if (result->tx_fd < 0) { printk(UM_KERN_ERR "uml_tap: failed to create tun interface: %i\n", result->tx_fd); goto hybrid_cleanup; } sock.sll_family = AF_PACKET; sock.sll_protocol = htons(ETH_P_ALL); sock.sll_ifindex = ifr.ifr_ifindex; /* RAW */ if (bind(fd, (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { result->rx_fd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL); if (result->rx_fd == -1) { printk(UM_KERN_ERR "user_init_tap: failed to bind raw pair, err %d\n", -errno); goto tap_cleanup; "uml_tap: failed to create paired raw socket: %i\n", result->rx_fd); goto hybrid_cleanup; } return result; tap_cleanup: printk(UM_KERN_ERR "user_init_tap: init failed, error %d", err); if (result != NULL) { if (result->rx_fd >= 0) os_close_file(result->rx_fd); if (result->tx_fd >= 0) os_close_file(result->tx_fd); hybrid_cleanup: printk(UM_KERN_ERR "user_init_hybrid: init failed"); if (result != NULL) kfree(result); } return NULL; } static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) { struct ifreq ifr; int rxfd = -1, txfd = -1; struct sockaddr_ll sock; int err = -ENOMEM; char *iface; struct vector_fds *result = NULL; iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); if (iface == NULL) goto cleanup; goto raw_cleanup; rxfd = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); rxfd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL); if (rxfd == -1) { err = -errno; goto cleanup; goto raw_cleanup; } txfd = socket(AF_PACKET, SOCK_RAW, 0); /* Turn off RX on this fd */ txfd = create_raw_fd(iface, 0, ETH_P_IP); /* Turn off RX on this fd */ if (txfd == -1) { err = -errno; goto cleanup; } memset(&ifr, 0, sizeof(ifr)); strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); if (ioctl(rxfd, SIOCGIFINDEX, (void *) &ifr) < 0) { err = -errno; goto cleanup; } sock.sll_family = AF_PACKET; sock.sll_protocol = htons(ETH_P_ALL); sock.sll_ifindex = ifr.ifr_ifindex; if (bind(rxfd, (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { err = -errno; goto cleanup; goto raw_cleanup; } sock.sll_family = AF_PACKET; sock.sll_protocol = htons(ETH_P_IP); sock.sll_ifindex = ifr.ifr_ifindex; if (bind(txfd, (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { err = -errno; goto cleanup; } result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); if (result != NULL) { result->rx_fd = rxfd; Loading @@ -260,12 +295,9 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) result->remote_addr_size = 0; } return result; cleanup: raw_cleanup: printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err); if (rxfd >= 0) os_close_file(rxfd); if (txfd >= 0) os_close_file(txfd); if (result != NULL) kfree(result); return NULL; } Loading Loading @@ -456,6 +488,8 @@ struct vector_fds *uml_vector_user_open( } if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0) return user_init_raw_fds(parsed); if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0) return user_init_hybrid_fds(parsed); if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0) return user_init_tap_fds(parsed); if (strncmp(transport, TRANS_GRE, TRANS_GRE_LEN) == 0) Loading @@ -482,8 +516,9 @@ int uml_vector_sendmsg(int fd, void *hdr, int flags) int uml_vector_recvmsg(int fd, void *hdr, int flags) { int n; struct msghdr *msg = (struct msghdr *) hdr; CATCH_EINTR(n = recvmsg(fd, (struct msghdr *) hdr, flags)); CATCH_EINTR(n = readv(fd, msg->msg_iov, msg->msg_iovlen)); if ((n < 0) && (errno == EAGAIN)) return 0; if (n >= 0) Loading arch/um/drivers/vector_user.h +3 −1 Original line number Diff line number Diff line Loading @@ -16,13 +16,15 @@ #define TRANS_TAP "tap" #define TRANS_TAP_LEN strlen(TRANS_TAP) #define TRANS_GRE "gre" #define TRANS_GRE_LEN strlen(TRANS_RAW) #define TRANS_L2TPV3 "l2tpv3" #define TRANS_L2TPV3_LEN strlen(TRANS_L2TPV3) #define TRANS_HYBRID "hybrid" #define TRANS_HYBRID_LEN strlen(TRANS_HYBRID) #ifndef IPPROTO_GRE #define IPPROTO_GRE 0x2F #endif Loading Loading
arch/um/drivers/vector_kern.c +2 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,8 @@ static int get_transport_options(struct arglist *def) if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0) return 0; if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0) return (vec_rx | VECTOR_BPF); if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0) return (vec_rx | vec_tx | VECTOR_QDISC_BYPASS); Loading
arch/um/drivers/vector_transports.c +27 −2 Original line number Diff line number Diff line Loading @@ -418,7 +418,7 @@ static int build_raw_transport_data(struct vector_private *vp) return 0; } static int build_tap_transport_data(struct vector_private *vp) static int build_hybrid_transport_data(struct vector_private *vp) { if (uml_raw_enable_vnet_headers(vp->fds->rx_fd)) { vp->form_header = &raw_form_header; Loading @@ -432,7 +432,7 @@ static int build_tap_transport_data(struct vector_private *vp) NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); netdev_info( vp->dev, "tap/raw: using vnet headers for tso and tx/rx checksum" "tap/raw hybrid: using vnet headers for tso and tx/rx checksum" ); } else { return 0; /* do not try to enable tap too if raw failed */ Loading @@ -442,6 +442,29 @@ static int build_tap_transport_data(struct vector_private *vp) return -1; } static int build_tap_transport_data(struct vector_private *vp) { /* "Pure" tap uses the same fd for rx and tx */ if (uml_tap_enable_vnet_headers(vp->fds->tx_fd)) { vp->form_header = &raw_form_header; vp->verify_header = &raw_verify_header; vp->header_size = sizeof(struct virtio_net_hdr); vp->rx_header_size = sizeof(struct virtio_net_hdr); vp->dev->hw_features |= (NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); vp->dev->features |= (NETIF_F_RXCSUM | NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); netdev_info( vp->dev, "tap: using vnet headers for tso and tx/rx checksum" ); return 0; } return -1; } int build_transport_data(struct vector_private *vp) { char *transport = uml_vector_fetch_arg(vp->parsed, "transport"); Loading @@ -454,6 +477,8 @@ int build_transport_data(struct vector_private *vp) return build_raw_transport_data(vp); if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0) return build_tap_transport_data(vp); if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0) return build_hybrid_transport_data(vp); return 0; }
arch/um/drivers/vector_user.c +119 −84 Original line number Diff line number Diff line Loading @@ -114,12 +114,76 @@ struct arglist *uml_parse_vector_ifspec(char *arg) #define PATH_NET_TUN "/dev/net/tun" static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) static int create_tap_fd(char *iface) { struct ifreq ifr; int fd = -1; struct sockaddr_ll sock; int err = -ENOMEM, offload; fd = open(PATH_NET_TUN, O_RDWR); if (fd < 0) { printk(UM_KERN_ERR "uml_tap: failed to open tun device\n"); goto tap_fd_cleanup; } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR; strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); err = ioctl(fd, TUNSETIFF, (void *) &ifr); if (err != 0) { printk(UM_KERN_ERR "uml_tap: failed to select tap interface\n"); goto tap_fd_cleanup; } offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6; ioctl(fd, TUNSETOFFLOAD, offload); return fd; tap_fd_cleanup: if (fd >= 0) os_close_file(fd); return err; } static int create_raw_fd(char *iface, int flags, int proto) { struct ifreq ifr; int fd = -1; struct sockaddr_ll sock; int err = -ENOMEM; fd = socket(AF_PACKET, SOCK_RAW, flags); if (fd == -1) { err = -errno; goto raw_fd_cleanup; } memset(&ifr, 0, sizeof(ifr)); strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) { err = -errno; goto raw_fd_cleanup; } sock.sll_family = AF_PACKET; sock.sll_protocol = htons(proto); sock.sll_ifindex = ifr.ifr_ifindex; if (bind(fd, (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { err = -errno; goto raw_fd_cleanup; } return fd; raw_fd_cleanup: printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err); if (fd >= 0) os_close_file(fd); return err; } static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) { int fd = -1; char *iface; struct vector_fds *result = NULL; Loading @@ -141,117 +205,88 @@ static struct vector_fds *user_init_tap_fds(struct arglist *ifspec) /* TAP */ fd = open(PATH_NET_TUN, O_RDWR); fd = create_tap_fd(iface); if (fd < 0) { printk(UM_KERN_ERR "uml_tap: failed to open tun device\n"); printk(UM_KERN_ERR "uml_tap: failed to create tun interface\n"); goto tap_cleanup; } result->tx_fd = fd; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR; strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); err = ioctl(fd, TUNSETIFF, (void *) &ifr); if (err != 0) { printk(UM_KERN_ERR "uml_tap: failed to select tap interface\n"); goto tap_cleanup; result->rx_fd = fd; return result; tap_cleanup: printk(UM_KERN_ERR "user_init_tap: init failed, error %d", fd); if (result != NULL) kfree(result); return NULL; } offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6; ioctl(fd, TUNSETOFFLOAD, offload); static struct vector_fds *user_init_hybrid_fds(struct arglist *ifspec) { char *iface; struct vector_fds *result = NULL; /* RAW */ iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); if (iface == NULL) { printk(UM_KERN_ERR "uml_tap: failed to parse interface spec\n"); goto hybrid_cleanup; } fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (fd == -1) { printk(UM_KERN_ERR "uml_tap: failed to create socket: %i\n", -errno); goto tap_cleanup; result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); if (result == NULL) { printk(UM_KERN_ERR "uml_tap: failed to allocate file descriptors\n"); goto hybrid_cleanup; } result->rx_fd = fd; memset(&ifr, 0, sizeof(ifr)); strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) { printk(UM_KERN_ERR "uml_tap: failed to set interface: %i\n", -errno); goto tap_cleanup; result->rx_fd = -1; result->tx_fd = -1; result->remote_addr = NULL; result->remote_addr_size = 0; /* TAP */ result->tx_fd = create_tap_fd(iface); if (result->tx_fd < 0) { printk(UM_KERN_ERR "uml_tap: failed to create tun interface: %i\n", result->tx_fd); goto hybrid_cleanup; } sock.sll_family = AF_PACKET; sock.sll_protocol = htons(ETH_P_ALL); sock.sll_ifindex = ifr.ifr_ifindex; /* RAW */ if (bind(fd, (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { result->rx_fd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL); if (result->rx_fd == -1) { printk(UM_KERN_ERR "user_init_tap: failed to bind raw pair, err %d\n", -errno); goto tap_cleanup; "uml_tap: failed to create paired raw socket: %i\n", result->rx_fd); goto hybrid_cleanup; } return result; tap_cleanup: printk(UM_KERN_ERR "user_init_tap: init failed, error %d", err); if (result != NULL) { if (result->rx_fd >= 0) os_close_file(result->rx_fd); if (result->tx_fd >= 0) os_close_file(result->tx_fd); hybrid_cleanup: printk(UM_KERN_ERR "user_init_hybrid: init failed"); if (result != NULL) kfree(result); } return NULL; } static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) { struct ifreq ifr; int rxfd = -1, txfd = -1; struct sockaddr_ll sock; int err = -ENOMEM; char *iface; struct vector_fds *result = NULL; iface = uml_vector_fetch_arg(ifspec, TOKEN_IFNAME); if (iface == NULL) goto cleanup; goto raw_cleanup; rxfd = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); rxfd = create_raw_fd(iface, ETH_P_ALL, ETH_P_ALL); if (rxfd == -1) { err = -errno; goto cleanup; goto raw_cleanup; } txfd = socket(AF_PACKET, SOCK_RAW, 0); /* Turn off RX on this fd */ txfd = create_raw_fd(iface, 0, ETH_P_IP); /* Turn off RX on this fd */ if (txfd == -1) { err = -errno; goto cleanup; } memset(&ifr, 0, sizeof(ifr)); strncpy((char *)&ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); if (ioctl(rxfd, SIOCGIFINDEX, (void *) &ifr) < 0) { err = -errno; goto cleanup; } sock.sll_family = AF_PACKET; sock.sll_protocol = htons(ETH_P_ALL); sock.sll_ifindex = ifr.ifr_ifindex; if (bind(rxfd, (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { err = -errno; goto cleanup; goto raw_cleanup; } sock.sll_family = AF_PACKET; sock.sll_protocol = htons(ETH_P_IP); sock.sll_ifindex = ifr.ifr_ifindex; if (bind(txfd, (struct sockaddr *) &sock, sizeof(struct sockaddr_ll)) < 0) { err = -errno; goto cleanup; } result = uml_kmalloc(sizeof(struct vector_fds), UM_GFP_KERNEL); if (result != NULL) { result->rx_fd = rxfd; Loading @@ -260,12 +295,9 @@ static struct vector_fds *user_init_raw_fds(struct arglist *ifspec) result->remote_addr_size = 0; } return result; cleanup: raw_cleanup: printk(UM_KERN_ERR "user_init_raw: init failed, error %d", err); if (rxfd >= 0) os_close_file(rxfd); if (txfd >= 0) os_close_file(txfd); if (result != NULL) kfree(result); return NULL; } Loading Loading @@ -456,6 +488,8 @@ struct vector_fds *uml_vector_user_open( } if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0) return user_init_raw_fds(parsed); if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0) return user_init_hybrid_fds(parsed); if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0) return user_init_tap_fds(parsed); if (strncmp(transport, TRANS_GRE, TRANS_GRE_LEN) == 0) Loading @@ -482,8 +516,9 @@ int uml_vector_sendmsg(int fd, void *hdr, int flags) int uml_vector_recvmsg(int fd, void *hdr, int flags) { int n; struct msghdr *msg = (struct msghdr *) hdr; CATCH_EINTR(n = recvmsg(fd, (struct msghdr *) hdr, flags)); CATCH_EINTR(n = readv(fd, msg->msg_iov, msg->msg_iovlen)); if ((n < 0) && (errno == EAGAIN)) return 0; if (n >= 0) Loading
arch/um/drivers/vector_user.h +3 −1 Original line number Diff line number Diff line Loading @@ -16,13 +16,15 @@ #define TRANS_TAP "tap" #define TRANS_TAP_LEN strlen(TRANS_TAP) #define TRANS_GRE "gre" #define TRANS_GRE_LEN strlen(TRANS_RAW) #define TRANS_L2TPV3 "l2tpv3" #define TRANS_L2TPV3_LEN strlen(TRANS_L2TPV3) #define TRANS_HYBRID "hybrid" #define TRANS_HYBRID_LEN strlen(TRANS_HYBRID) #ifndef IPPROTO_GRE #define IPPROTO_GRE 0x2F #endif Loading