From patchwork Mon Apr 2 21:37:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Varghese, Vipin" X-Patchwork-Id: 36878 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 439575F16; Mon, 2 Apr 2018 17:56:02 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 9A02E2C01 for ; Mon, 2 Apr 2018 17:56:00 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Apr 2018 08:55:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,396,1517904000"; d="scan'208";a="38782520" Received: from unknown (HELO localhost.localdomain) ([10.224.122.203]) by FMSMGA003.fm.intel.com with ESMTP; 02 Apr 2018 08:55:56 -0700 From: Vipin Varghese To: dev@dpdk.org, pascal.mazon@6wind.com, ferruh.yigit@intel.com Cc: Vipin Varghese Date: Tue, 3 Apr 2018 03:07:47 +0530 Message-Id: <1522705068-18198-1-git-send-email-vipin.varghese@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1519625719-10443-1-git-send-email-vipin.varghese@intel.com> References: <1519625719-10443-1-git-send-email-vipin.varghese@intel.com> Subject: [dpdk-dev] [PATCH 1/2] net/tap: add tun support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The change adds functional TUN PMD logic to the existing TAP PMD. TUN PMD can be initialized with 'net_tunX' where 'X' represents unique id. PMD supports argument interface, while MAC address and remote are not supported. Signed-off-by: Vipin Varghese Reviewed-by: Ferruh Yigit Acked-by: Pascal Mazon --- Changes in V3: - fix the TUN kernel packet error - Vipin - seperate out function from logging - Ferruh - add TUN PMD_REGISTER_PARAM_STRING - Ferruh Changes in V2: - updated the documentation word error - Pascal --- drivers/net/tap/rte_eth_tap.c | 117 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 105 insertions(+), 12 deletions(-) diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index 3e4f7a8..295db3c 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -42,6 +42,7 @@ /* Linux based path to the TUN device */ #define TUN_TAP_DEV_PATH "/dev/net/tun" #define DEFAULT_TAP_NAME "dtap" +#define DEFAULT_TUN_NAME "dtun" #define ETH_TAP_IFACE_ARG "iface" #define ETH_TAP_REMOTE_ARG "remote" @@ -53,6 +54,7 @@ #define ETH_TAP_MAC_ARG_FMT ETH_TAP_MAC_FIXED "|" ETH_TAP_USR_MAC_FMT static struct rte_vdev_driver pmd_tap_drv; +static struct rte_vdev_driver pmd_tun_drv; static const char *valid_arguments[] = { ETH_TAP_IFACE_ARG, @@ -62,6 +64,10 @@ }; static int tap_unit; +static int tun_unit; + +static int tap_type; +static char tuntap_name[8]; static volatile uint32_t tap_trigger; /* Rx trigger */ @@ -108,7 +114,7 @@ enum ioctl_mode { * Do not set IFF_NO_PI as packet information header will be needed * to check if a received packet has been truncated. */ - ifr.ifr_flags = IFF_TAP; + ifr.ifr_flags = (tap_type) ? IFF_TAP : IFF_TUN | IFF_POINTOPOINT; snprintf(ifr.ifr_name, IFNAMSIZ, "%s", pmd->name); RTE_LOG(DEBUG, PMD, "ifr_name '%s'\n", ifr.ifr_name); @@ -495,7 +501,7 @@ enum ioctl_mode { for (i = 0; i < nb_pkts; i++) { struct rte_mbuf *mbuf = bufs[num_tx]; struct iovec iovecs[mbuf->nb_segs + 1]; - struct tun_pi pi = { .flags = 0 }; + struct tun_pi pi = { .flags = 0, .proto = 0x00 }; struct rte_mbuf *seg = mbuf; char m_copy[mbuf->data_len]; int n; @@ -505,6 +511,21 @@ enum ioctl_mode { if (rte_pktmbuf_pkt_len(mbuf) > max_size) break; + /* + * TUN and TAP are created with IFF_NO_PI disabled. + * For TUN PMD this mandatory as fields are used by + * Kernel tun.c to determine whether its IP or non IP + * packets. + * + * The logic fetches the first byte of data from mbuf. + * compares whether its v4 or v6. If none matches default + * value 0x00 is taken for protocol field. + */ + char *buff_data = rte_pktmbuf_mtod(seg, void *); + j = (*buff_data & 0xf0); + if (j & (0x40 | 0x60)) + pi.proto = (j == 0x40) ? 0x0008 : 0xdd86; + iovecs[0].iov_base = π iovecs[0].iov_len = sizeof(pi); for (j = 1; j <= mbuf->nb_segs; j++) { @@ -1403,10 +1424,12 @@ enum ioctl_mode { pmd->txq[i].fd = -1; } - if (is_zero_ether_addr(mac_addr)) - eth_random_addr((uint8_t *)&pmd->eth_addr); - else - rte_memcpy(&pmd->eth_addr, mac_addr, sizeof(mac_addr)); + if (tap_type) { + if (is_zero_ether_addr(mac_addr)) + eth_random_addr((uint8_t *)&pmd->eth_addr); + else + rte_memcpy(&pmd->eth_addr, mac_addr, sizeof(mac_addr)); + } /* Immediately create the netdevice (this will create the 1st queue). */ /* rx queue */ @@ -1420,11 +1443,14 @@ enum ioctl_mode { if (tap_ioctl(pmd, SIOCSIFMTU, &ifr, 1, LOCAL_AND_REMOTE) < 0) goto error_exit; - memset(&ifr, 0, sizeof(struct ifreq)); - ifr.ifr_hwaddr.sa_family = AF_LOCAL; - rte_memcpy(ifr.ifr_hwaddr.sa_data, &pmd->eth_addr, ETHER_ADDR_LEN); - if (tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 0, LOCAL_ONLY) < 0) - goto error_exit; + if (tap_type) { + memset(&ifr, 0, sizeof(struct ifreq)); + ifr.ifr_hwaddr.sa_family = AF_LOCAL; + rte_memcpy(ifr.ifr_hwaddr.sa_data, &pmd->eth_addr, + ETHER_ADDR_LEN); + if (tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 0, LOCAL_ONLY) < 0) + goto error_exit; + } /* * Set up everything related to rte_flow: @@ -1621,6 +1647,62 @@ static int parse_user_mac(struct ether_addr *user_mac, return -1; } +/* + * Open a TUN interface device. TUN PMD + * 1) sets tap_type as false + * 2) intakes iface as argument. + * 3) as interface is virtual set speed to 10G + */ +static int +rte_pmd_tun_probe(struct rte_vdev_device *dev) +{ + const char *name, *params; + int ret; + struct rte_kvargs *kvlist = NULL; + char tun_name[RTE_ETH_NAME_MAX_LEN]; + char remote_iface[RTE_ETH_NAME_MAX_LEN]; + + tap_type = 0; + strcpy(tuntap_name, "TUN"); + + name = rte_vdev_device_name(dev); + params = rte_vdev_device_args(dev); + memset(remote_iface, 0, RTE_ETH_NAME_MAX_LEN); + + if (params && (params[0] != '\0')) { + RTE_LOG(DEBUG, PMD, "parameters (%s)\n", params); + + kvlist = rte_kvargs_parse(params, valid_arguments); + if (kvlist) { + if (rte_kvargs_count(kvlist, ETH_TAP_IFACE_ARG) == 1) { + ret = rte_kvargs_process(kvlist, + ETH_TAP_IFACE_ARG, + &set_interface_name, + tun_name); + + if (ret == -1) + goto leave; + } + } + } + pmd_link.link_speed = ETH_SPEED_NUM_10G; + + RTE_LOG(NOTICE, PMD, "Initializing pmd_tun for %s as %s\n", + name, tun_name); + + ret = eth_dev_tap_create(dev, tun_name, remote_iface, 0); + +leave: + if (ret == -1) { + RTE_LOG(ERR, PMD, "Failed to create pmd for %s as %s\n", + name, tun_name); + tun_unit--; /* Restore the unit number */ + } + rte_kvargs_free(kvlist); + + return ret; +} + /* Open a TAP interface device. */ static int @@ -1634,6 +1716,9 @@ static int parse_user_mac(struct ether_addr *user_mac, char remote_iface[RTE_ETH_NAME_MAX_LEN]; struct ether_addr user_mac = { .addr_bytes = {0} }; + tap_type = 1; + strcpy(tuntap_name, "TAP"); + name = rte_vdev_device_name(dev); params = rte_vdev_device_args(dev); @@ -1693,7 +1778,7 @@ static int parse_user_mac(struct ether_addr *user_mac, return ret; } -/* detach a TAP device. +/* detach a TUNTAP device. */ static int rte_pmd_tap_remove(struct rte_vdev_device *dev) @@ -1736,12 +1821,20 @@ static int parse_user_mac(struct ether_addr *user_mac, return 0; } +static struct rte_vdev_driver pmd_tun_drv = { + .probe = rte_pmd_tun_probe, + .remove = rte_pmd_tap_remove, +}; + static struct rte_vdev_driver pmd_tap_drv = { .probe = rte_pmd_tap_probe, .remove = rte_pmd_tap_remove, }; RTE_PMD_REGISTER_VDEV(net_tap, pmd_tap_drv); +RTE_PMD_REGISTER_VDEV(net_tun, pmd_tun_drv); RTE_PMD_REGISTER_ALIAS(net_tap, eth_tap); +RTE_PMD_REGISTER_PARAM_STRING(net_tun, + ETH_TAP_IFACE_ARG "= "); RTE_PMD_REGISTER_PARAM_STRING(net_tap, ETH_TAP_IFACE_ARG "= " ETH_TAP_MAC_ARG "=" ETH_TAP_MAC_ARG_FMT " "