From patchwork Tue Aug 9 19:34:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 114789 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 29A3FA04FD; Tue, 9 Aug 2022 21:34:17 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C4CB74113F; Tue, 9 Aug 2022 21:34:16 +0200 (CEST) Received: from mail-pg1-f173.google.com (mail-pg1-f173.google.com [209.85.215.173]) by mails.dpdk.org (Postfix) with ESMTP id 1322B40143 for ; Tue, 9 Aug 2022 21:34:14 +0200 (CEST) Received: by mail-pg1-f173.google.com with SMTP id c24so7426156pgg.11 for ; Tue, 09 Aug 2022 12:34:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Y2sGO+N4HVlp5F1DM/DZh1zOzbhXkBlcfLLg2wBcJik=; b=HFTNx0iNOsqJ7Lvit+1wO6hPD2Ieg7ssEjQwImZQ+1+SlVK61YdALNdt7bwcL9cISU EcNo0Zx0tnIlg9KeKkrvb8T3uzhxs4x6pwm/HFbqlVGS4x/hE9Q2LU+MhAz+tf6BXfsS RvfoUcSSBTGp36q4f/jqal19qazQNbdUKLPsCZ2PJWSiUQNRutT4Bz8maDBT5AW/0fis 8VrDLoM/AYzWT5YrGtfJkimYI6qhjiVwX81dYFtzValiD976Lz4RUolUqC6D297j28dD uwVGit5HJjDGGx7VHF2aX6UQFYF6uLajeVcPFByYagVCdvEtzNpcdOiH1DyhpNUHurpi KtvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Y2sGO+N4HVlp5F1DM/DZh1zOzbhXkBlcfLLg2wBcJik=; b=bcDoArasUbbBCmXrTlaPWz3+SDjoOnW7d/RnjYIrHhsHyo4ygrKW/wvHSuQEhZ0nXI W/+58ztpDlhUZ2HSt1PAdQP7yS+V37Lv/gYSs+3vYnvoAkwZzlVOKLkoVcygU7lJiTvX DA1n0fRkg7PSUjzzZriQTYGyk/CZHcqp49/W8+aL3GFES+Z2rnuQoV2uOS6IAOaMSAeI H+zfZUYsYsTIUTV3f0Qsn7vZ8IveIdvNurHTwtjky6OOppJWvC+GVyXGrOdyCT3V5Pbl J8/sZBJoNflG3ojZtxfEIlwecjMDBt1TWzSKsvuQiPbFKBLVG56+8SU6gtcHkeHr+z70 jnrg== X-Gm-Message-State: ACgBeo1tW6fmY63tySxB+0EdHbF8aLjs9XnhrfFy3bC/03Kkd6I+SvEC VswiqzpRyuwvXJiO761qO8Ry8AKMtGJCQA== X-Google-Smtp-Source: AA6agR6/dx8npwqRdEW7CtkjpHP3jNaujx1U/gOqjL8MNap/3jNhRYbPOvRa0rgcoFQnn4jnbKZbiQ== X-Received: by 2002:aa7:8421:0:b0:52d:344f:8674 with SMTP id q1-20020aa78421000000b0052d344f8674mr24251137pfn.60.1660073653911; Tue, 09 Aug 2022 12:34:13 -0700 (PDT) Received: from hermes.local (204-195-120-218.wavecable.com. [204.195.120.218]) by smtp.gmail.com with ESMTPSA id e11-20020a17090301cb00b0016db6bd77f4sm11468463plh.117.2022.08.09.12.34.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 12:34:13 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH] net/tap: add persist option Date: Tue, 9 Aug 2022 12:34:11 -0700 Message-Id: <20220809193411.182392-1-stephen@networkplumber.org> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The TAP device only lasts as long as the DPDK application that opened it is running. This behavior is basd if the DPDK application needs to be updated transparently without disturbing other services using the tap device. This patch adds a persist feature to the TAP device. If this flag is set, the kernel network device remains even if after the application has exited. Signed-off-by: Stephen Hemminger Reviewed-by: Andrew Rybchenko --- doc/guides/nics/tap.rst | 6 ++++++ drivers/net/tap/rte_eth_tap.c | 39 ++++++++++++++++++++++++++++------- drivers/net/tap/rte_eth_tap.h | 1 + 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/doc/guides/nics/tap.rst b/doc/guides/nics/tap.rst index 3d4564b04612..c5a8c69a7274 100644 --- a/doc/guides/nics/tap.rst +++ b/doc/guides/nics/tap.rst @@ -83,6 +83,12 @@ can utilize that stack to handle the network protocols. Plus you would be able to address the interface using an IP address assigned to the internal interface. +Normally, when the DPDK application exits the TAP device is marked down and +is removed. But this behaviour can be overridden by the use of the persist +flag, example:: + + --vdev=net_tap0,iface=tap0,persist ... + The TUN PMD allows user to create a TUN device on host. The PMD allows user to transmit and receive packets via DPDK API calls with L3 header and payload. The devices in host can be accessed via ``ifconfig`` or ``ip`` command. TUN diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index 9e1032fe7269..07b6bd7365ef 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -54,6 +54,7 @@ #define ETH_TAP_REMOTE_ARG "remote" #define ETH_TAP_MAC_ARG "mac" #define ETH_TAP_MAC_FIXED "fixed" +#define ETH_TAP_PERSIST_ARG "persist" #define ETH_TAP_USR_MAC_FMT "xx:xx:xx:xx:xx:xx" #define ETH_TAP_CMP_MAC_FMT "0123456789ABCDEFabcdef" @@ -92,6 +93,7 @@ static const char *valid_arguments[] = { ETH_TAP_IFACE_ARG, ETH_TAP_REMOTE_ARG, ETH_TAP_MAC_ARG, + ETH_TAP_PERSIST_ARG, NULL }; @@ -140,11 +142,14 @@ static int tap_intr_handle_set(struct rte_eth_dev *dev, int set); * @param[in] is_keepalive * Keepalive flag * + * @param[in] persistent + * Mark device as persistent + * * @return * -1 on failure, fd on success */ static int -tun_alloc(struct pmd_internals *pmd, int is_keepalive) +tun_alloc(struct pmd_internals *pmd, int is_keepalive, int persistent) { struct ifreq ifr; #ifdef IFF_MULTI_QUEUE @@ -194,6 +199,14 @@ tun_alloc(struct pmd_internals *pmd, int is_keepalive) goto error; } + /* Keep the device after application exit */ + if (persistent && ioctl(fd, TUNSETPERSIST, 1) < 0) { + TAP_LOG(WARNING, + "Unable to set persist %s: %s", + ifr.ifr_name, strerror(errno)); + goto error; + } + /* * Name passed to kernel might be wildcard like dtun%d * and need to find the resulting device. @@ -973,6 +986,7 @@ tap_mp_req_start_rxtx(const struct rte_mp_msg *request, __rte_unused const void static int tap_dev_stop(struct rte_eth_dev *dev) { + struct pmd_internals *pmd = dev->data->dev_private; int i; for (i = 0; i < dev->data->nb_tx_queues; i++) @@ -981,7 +995,8 @@ tap_dev_stop(struct rte_eth_dev *dev) dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; tap_intr_handle_set(dev, 0); - tap_link_set_down(dev); + if (!pmd->persist) + tap_link_set_down(dev); return 0; } @@ -1165,7 +1180,8 @@ tap_dev_close(struct rte_eth_dev *dev) return 0; } - tap_link_set_down(dev); + if (!internals->persist) + tap_link_set_down(dev); if (internals->nlsk_fd != -1) { tap_flow_flush(dev, NULL); tap_flow_implicit_flush(internals, NULL); @@ -1553,7 +1569,7 @@ tap_setup_queue(struct rte_eth_dev *dev, pmd->name, *other_fd, dir, qid, *fd); } else { /* Both RX and TX fds do not exist (equal -1). Create fd */ - *fd = tun_alloc(pmd, 0); + *fd = tun_alloc(pmd, 0, 0); if (*fd < 0) { *fd = -1; /* restore original value */ TAP_LOG(ERR, "%s: tun_alloc() failed.", pmd->name); @@ -1958,7 +1974,7 @@ static const struct eth_dev_ops ops = { static int eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, char *remote_iface, struct rte_ether_addr *mac_addr, - enum rte_tuntap_type type) + enum rte_tuntap_type type, int persist) { int numa_node = rte_socket_id(); struct rte_eth_dev *dev; @@ -2050,7 +2066,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, * This keep-alive file descriptor will guarantee that the TUN device * exists even when all of its queues are closed */ - pmd->ka_fd = tun_alloc(pmd, 1); + pmd->ka_fd = tun_alloc(pmd, 1, persist); if (pmd->ka_fd == -1) { TAP_LOG(ERR, "Unable to create %s interface", tuntap_name); goto error_exit; @@ -2070,6 +2086,9 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, goto error_exit; } + /* Make network device persist after application exit */ + pmd->persist = persist; + /* * Set up everything related to rte_flow: * - netlink socket @@ -2360,7 +2379,7 @@ rte_pmd_tun_probe(struct rte_vdev_device *dev) TAP_LOG(DEBUG, "Initializing pmd_tun for %s", name); ret = eth_dev_tap_create(dev, tun_name, remote_iface, 0, - ETH_TUNTAP_TYPE_TUN); + ETH_TUNTAP_TYPE_TUN, 0); leave: if (ret == -1) { @@ -2490,6 +2509,7 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) struct rte_ether_addr user_mac = { .addr_bytes = {0} }; struct rte_eth_dev *eth_dev; int tap_devices_count_increased = 0; + int persist = 0; name = rte_vdev_device_name(dev); params = rte_vdev_device_args(dev); @@ -2573,6 +2593,9 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) if (ret == -1) goto leave; } + + if (rte_kvargs_count(kvlist, ETH_TAP_PERSIST_ARG) == 1) + persist = 1; } } pmd_link.link_speed = speed; @@ -2591,7 +2614,7 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) tap_devices_count++; tap_devices_count_increased = 1; ret = eth_dev_tap_create(dev, tap_name, remote_iface, &user_mac, - ETH_TUNTAP_TYPE_TAP); + ETH_TUNTAP_TYPE_TAP, persist); leave: if (ret == -1) { diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h index 996021e424fd..5ac93f93e961 100644 --- a/drivers/net/tap/rte_eth_tap.h +++ b/drivers/net/tap/rte_eth_tap.h @@ -80,6 +80,7 @@ struct pmd_internals { int flower_support; /* 1 if kernel supports, else 0 */ int flower_vlan_support; /* 1 if kernel supports, else 0 */ int rss_enabled; /* 1 if RSS is enabled, else 0 */ + int persist; /* 1 if keep link up, else 0 */ /* implicit rules set when RSS is enabled */ int map_fd; /* BPF RSS map fd */ int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */