From patchwork Mon Dec 14 02:19:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tonghao Zhang X-Patchwork-Id: 1415728 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=TDVuHGJc; dkim-atps=neutral Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CvQC06mF0z9sTX for ; Mon, 14 Dec 2020 13:22:19 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 66A9D85AE9; Mon, 14 Dec 2020 02:22:17 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NggZZdLSLo97; Mon, 14 Dec 2020 02:22:15 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 08D7A85AA1; Mon, 14 Dec 2020 02:22:15 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id E09C9C088E; Mon, 14 Dec 2020 02:22:14 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 94BC3C013B for ; Mon, 14 Dec 2020 02:22:13 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 7FF7785A78 for ; Mon, 14 Dec 2020 02:22:13 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id iCU2VEfxWsbo for ; Mon, 14 Dec 2020 02:22:12 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-pl1-f195.google.com (mail-pl1-f195.google.com [209.85.214.195]) by fraxinus.osuosl.org (Postfix) with ESMTPS id AF71185A22 for ; Mon, 14 Dec 2020 02:22:12 +0000 (UTC) Received: by mail-pl1-f195.google.com with SMTP id v3so7805583plz.13 for ; Sun, 13 Dec 2020 18:22:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=aO41yoEwDPhUn0NXYAnAz4ACp3rhpyCTssw1Bedvisk=; b=TDVuHGJc8Xhh5sAtUuRldPOfKx3TWsn0uMUL3hdIQL0icyHdslFv/5GMfd8jWam10u E0IaVKeehdojwelRChYsNWe5oOwbeTEwv6Lj6FABZxpnL+3ATCyDTM1LJq6/sNFaKhJs Oz+JeEE9n4u+wxrIK7DspVaInavvPYlwkMa+uAtYE8y4Amtb9Uwzwcq7H76pF76LpcZ/ LGtVvP0az/WjkEoimyjs/LQYI4wZGWAfxFCGnK72FMxkEnw6IpBF/daJCnzsF2vMHX5l Ri7nWXZjhIJPiYqbozgDXBYJYvhNR60Lp092xGDzpDO2jidw+uA7ebfwK2cBi44qH88g zAfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=aO41yoEwDPhUn0NXYAnAz4ACp3rhpyCTssw1Bedvisk=; b=Hdb7tanL2VWmG2mQUyYqm0dWntwWe8PRPxuXmSd0EW4rNL9JBHrgQILzo5pvjYcuiw GylGg5LgsUwM1XA81Dp2wte/Tb2TJBwvwQ9YcauGKDB+SJWMYNfpYbmI6ChRaIDCUFsh xG86QnNyfd4K8PEQ8+r12arvwNN30s2bTEaQzEltBmhu7y8hMKSwkDgq6h6BXUZHLVmG jAbMTscihLaQnKE+LmEDd5IX64KgjmuPRziN3Y1o6VsdRDGrT1HtzDjs/XTVMfl6OzRy nT3C4puBHGP4QHfds74drIY8n0bo0bNXbJyAu/hymNzm57gQ/kbcnUHlse7iC8IuvMBg 0wBQ== X-Gm-Message-State: AOAM532v8kgK14x0mdZWrSN/rYd3F87/+FVhCmADdCWqUioQn9ztzEMT CLJNzjAGLVPNKrQktEd0uVWfjZ4YtD0= X-Google-Smtp-Source: ABdhPJxshLJprPruqEd2RvM5SEhgIcuYaKOHpLaUWCQcUmtnEpNbae0Iaj6n/JvyFRLGIMcupcaM0w== X-Received: by 2002:a17:90a:bb83:: with SMTP id v3mr23032780pjr.28.1607912532280; Sun, 13 Dec 2020 18:22:12 -0800 (PST) Received: from localhost.localdomain ([50.236.19.102]) by smtp.gmail.com with ESMTPSA id z7sm18019540pfq.193.2020.12.13.18.22.09 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 13 Dec 2020 18:22:11 -0800 (PST) From: xiangxia.m.yue@gmail.com To: blp@ovn.org, i.maximets@ovn.org, u9012063@gmail.com, elibr@nvidia.com Date: Mon, 14 Dec 2020 10:19:58 +0800 Message-Id: <20201214022001.84273-2-xiangxia.m.yue@gmail.com> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20201214022001.84273-1-xiangxia.m.yue@gmail.com> References: <20201214022001.84273-1-xiangxia.m.yue@gmail.com> Cc: dev@openvswitch.org Subject: [ovs-dev] [PATCH ovs v1 1/4] netdev-dpdk: Allow to config isolate offload mode. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Tonghao Zhang Isolated mode guarantees that all ingress traffic comes from defined flow rules only (current and future). Besides making ingress more deterministic, it allows PMDs to safely reuse resources otherwise assigned to handle the remaining traffic, such as global RSS configuration settings, VLAN filters, MAC address entries, legacy filter API rules and so on in order to expand the set of possible flow rule types. Calling this function as soon as possible after device initialization, ideally before the first call to rte_eth_dev_configure(), is recommended to avoid possible failures due to conflicting settings. Once effective, leaving isolated mode may not be possible depending on PMD implementation. Signed-off-by: Tonghao Zhang --- lib/netdev-dpdk.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 75dffefb8..48eb46f38 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -522,6 +522,10 @@ struct netdev_dpdk { * otherwise interrupt mode is used. */ bool requested_lsc_interrupt_mode; bool lsc_interrupt_mode; + /* Allow to use hardware capable ethernet devices to + * split traffic between userspace and kernel space. */ + bool requested_isolate_offload_mode; + bool isolate_offload_mode; /* VF configuration. */ struct eth_addr requested_hwaddr; @@ -965,6 +969,13 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, int n_rxq, int n_txq) struct rte_eth_dev_info info; uint16_t conf_mtu; + diag = rte_flow_isolate(dev->port_id, dev->isolate_offload_mode, NULL); + if (diag && diag != -ENOSYS) { + VLOG_WARN("rte_flow_isolate was invoked unsuccessfully, mode(%d): %d\n", + dev->isolate_offload_mode, diag); + return diag; + } + rte_eth_dev_info_get(dev->port_id, &info); /* As of DPDK 19.11, it is not allowed to set a mq_mode for @@ -1245,6 +1256,7 @@ common_construct(struct netdev *netdev, dpdk_port_t port_no, dev->requested_mtu = RTE_ETHER_MTU; dev->max_packet_len = MTU_TO_FRAME_LEN(dev->mtu); dev->requested_lsc_interrupt_mode = 0; + dev->requested_isolate_offload_mode = 0; ovsrcu_index_init(&dev->vid, -1); dev->vhost_reconfigured = false; dev->attached = false; @@ -1739,6 +1751,8 @@ netdev_dpdk_get_config(const struct netdev *netdev, struct smap *args) } smap_add(args, "lsc_interrupt_mode", dev->lsc_interrupt_mode ? "true" : "false"); + smap_add(args, "isolate_offload_mode", + dev->isolate_offload_mode ? "true" : "false"); if (dpdk_port_is_representor(dev)) { smap_add_format(args, "dpdk-vf-mac", ETH_ADDR_FMT, @@ -1918,6 +1932,7 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, bool rx_fc_en, tx_fc_en, autoneg, lsc_interrupt_mode; bool flow_control_requested = true; enum rte_eth_fc_mode fc_mode; + bool isolate_offload_mode; static const enum rte_eth_fc_mode fc_mode_set[2][2] = { {RTE_FC_NONE, RTE_FC_TX_PAUSE}, {RTE_FC_RX_PAUSE, RTE_FC_FULL } @@ -2022,6 +2037,12 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, netdev_request_reconfigure(netdev); } + isolate_offload_mode = smap_get_bool(args, "isolate-offload-mode", false); + if (dev->requested_isolate_offload_mode != isolate_offload_mode) { + dev->requested_isolate_offload_mode = isolate_offload_mode; + netdev_request_reconfigure(netdev); + } + rx_fc_en = smap_get_bool(args, "rx-flow-ctrl", false); tx_fc_en = smap_get_bool(args, "tx-flow-ctrl", false); autoneg = smap_get_bool(args, "flow-ctrl-autoneg", false); @@ -4985,6 +5006,7 @@ netdev_dpdk_reconfigure(struct netdev *netdev) && netdev->n_rxq == dev->requested_n_rxq && dev->mtu == dev->requested_mtu && dev->lsc_interrupt_mode == dev->requested_lsc_interrupt_mode + && dev->isolate_offload_mode == dev->requested_isolate_offload_mode && dev->rxq_size == dev->requested_rxq_size && dev->txq_size == dev->requested_txq_size && eth_addr_equals(dev->hwaddr, dev->requested_hwaddr) @@ -5011,6 +5033,7 @@ netdev_dpdk_reconfigure(struct netdev *netdev) } dev->lsc_interrupt_mode = dev->requested_lsc_interrupt_mode; + dev->isolate_offload_mode = dev->requested_isolate_offload_mode; netdev->n_txq = dev->requested_n_txq; netdev->n_rxq = dev->requested_n_rxq; From patchwork Mon Dec 14 02:19:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tonghao Zhang X-Patchwork-Id: 1415729 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=whitealder.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=W2NTl0Ax; dkim-atps=neutral Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CvQC76dpTz9sTX for ; Mon, 14 Dec 2020 13:22:26 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 0CAE286BE2; Mon, 14 Dec 2020 02:22:25 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NXvRmrqaIyN2; Mon, 14 Dec 2020 02:22:21 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id 0040686BB2; Mon, 14 Dec 2020 02:22:20 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id BA206C088E; Mon, 14 Dec 2020 02:22:20 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5270FC013B for ; Mon, 14 Dec 2020 02:22:19 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 3F65886BAD for ; Mon, 14 Dec 2020 02:22:19 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WSzpLgzjJnO4 for ; Mon, 14 Dec 2020 02:22:16 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-pj1-f66.google.com (mail-pj1-f66.google.com [209.85.216.66]) by whitealder.osuosl.org (Postfix) with ESMTPS id 38BBB86C0C for ; Mon, 14 Dec 2020 02:22:16 +0000 (UTC) Received: by mail-pj1-f66.google.com with SMTP id h7so4104552pjk.1 for ; Sun, 13 Dec 2020 18:22:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GBs/+nAptoV0TdG/fXoq3CgI3CJn9JgTroXv1K3JWZY=; b=W2NTl0AxmtS8aAn/C+DuyWm7U8Zv0q0iNEKKbq77mFusmnd1l1SjfNFE5OoOpBU3dT OiCMwQFt6f6ur87786x2ly0I6Yr5AF8tUanSPHoovdABQIJKDLtkHxKZjiGr/9I3V2og xCIRti9CbA25ZdZBQq9zE5r+7vDy7daiB8bMI7BcOlXPwvk6Xd0SZKpZxhgkXmedHY/m CesvwAn7WXEs7FdKeQfg4yQvjjqGPMS945MyH2BwXq3FVxjgfav4cI3XjJCF+2nzW8hm PPsqAKZL8WSEvqxc1NCK9v5fzEDNCh93U0LlyatHr8LUWKl0L98XdgJilutwFYz/STyA Qrng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=GBs/+nAptoV0TdG/fXoq3CgI3CJn9JgTroXv1K3JWZY=; b=NQcFIqPK66lZcJmBeJ3qS+pYPPE8zvSZGzAW686M2tFSZPzcfeNhfFfY/xJcc8QK13 SJZDDkNaT9QmRSAnxRjILM62c1jbqvpj3VOVtp8LKcS067CpaUIykcSBgJ4sXHO/himI mkxrWA9kv4UNwPSio58ERagTWML4iuVqMY7I1De7G/fz5VzmRJ3q+raAD/UZGETyu3sd oGyvM08G1RaqapT9B/IGaQnF9x1esNp8ZqRCQI965YlAIAbejJlRR9dQp1y+ZhDnMv1l NXSJ2Tfo6d/fsdpcAhzkiaDupmdHe+roxZ/giBu+IuDwq1CKG3LLvi2h4ZS5zUxwY0n1 7grg== X-Gm-Message-State: AOAM532WzVjZrS6iYsc9d9wscmvP1GKJBWB0KSXnPRT1Dbtun/SImVgH 3r0JpgW8khS9flU4MPSwlXk= X-Google-Smtp-Source: ABdhPJzd6rF6tOZ1CTXJY+ngDo2xVd2OK6c5zVRexBB9CuFFb31tmhD8EWjT2desRZVg0UuocVdsNg== X-Received: by 2002:a17:90b:4a4c:: with SMTP id lb12mr3325316pjb.162.1607912535786; Sun, 13 Dec 2020 18:22:15 -0800 (PST) Received: from localhost.localdomain ([50.236.19.102]) by smtp.gmail.com with ESMTPSA id z7sm18019540pfq.193.2020.12.13.18.22.12 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 13 Dec 2020 18:22:15 -0800 (PST) From: xiangxia.m.yue@gmail.com To: blp@ovn.org, i.maximets@ovn.org, u9012063@gmail.com, elibr@nvidia.com Date: Mon, 14 Dec 2020 10:19:59 +0800 Message-Id: <20201214022001.84273-3-xiangxia.m.yue@gmail.com> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20201214022001.84273-1-xiangxia.m.yue@gmail.com> References: <20201214022001.84273-1-xiangxia.m.yue@gmail.com> Cc: dev@openvswitch.org Subject: [ovs-dev] [PATCH ovs v1 2/4] dpctl: Add --consistent option. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Tonghao Zhang openvswitch is reactive, and then flows will be installed when receiving packets. This patch add --consistent for dpctl commands to allow user installing flows which will not be deleted. * This feature can be used with dpdk rte isolate offload mode. (e.g. receiving only tunnel packets.) * And users use it to debug openvswitch. Signed-off-by: Tonghao Zhang --- lib/dpctl.c | 24 ++++++++++++++++++++++++ lib/dpctl.h | 3 +++ lib/odp-util.c | 11 +++++++++++ lib/odp-util.h | 1 + lib/uuid.h | 3 +++ ofproto/ofproto-dpif-upcall.c | 7 +++++++ 6 files changed, 49 insertions(+) diff --git a/lib/dpctl.c b/lib/dpctl.c index 33202813b..d907eddb4 100644 --- a/lib/dpctl.c +++ b/lib/dpctl.c @@ -1146,6 +1146,12 @@ dpctl_put_flow(int argc, const char *argv[], enum dpif_flow_put_flags flags, ufid_present = true; } + if (ufid_present && dpctl_p->consistent) { + dpctl_error(dpctl_p, -1, + "ufid and consistent are enabled at same time."); + return -1; + } + simap_init(&port_names); DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) { simap_put(&port_names, dpif_port.name, odp_to_u32(dpif_port.port_no)); @@ -1169,6 +1175,11 @@ dpctl_put_flow(int argc, const char *argv[], enum dpif_flow_put_flags flags, goto out_freeactions; } + if (dpctl_p->consistent) { + odp_flow_key_hash_local(key.data, key.size, &ufid); + ufid_present = true; + } + if (!ufid_present && dpctl_p->is_appctl) { /* Generating UFID for this flow so it could be offloaded to HW. We're * not doing that if invoked from ovs-dpctl utility because @@ -1326,6 +1337,17 @@ dpctl_del_flow(int argc, const char *argv[], struct dpctl_params *dpctl_p) goto out; } + if (ufid_present && dpctl_p->consistent) { + dpctl_error(dpctl_p, -1, + "ufid and consistent are enabled at same time."); + goto out; + } + + if (dpctl_p->consistent) { + odp_flow_key_hash_local(key.data, key.size, &ufid); + ufid_present = ufid_generated = true; + } + if (!ufid_present && dpctl_p->is_appctl) { /* While adding flow via appctl we're generating UFID to make HW * offloading possible. Generating UFID here to be sure that such @@ -2670,6 +2692,8 @@ dpctl_unixctl_handler(struct unixctl_conn *conn, int argc, const char *argv[], } else if (!strcmp(arg, "--no-names")) { dpctl_p.names = false; set_names = true; + } else if (!strcmp(arg, "--consistent")) { + dpctl_p.consistent = true; } else { ds_put_format(&ds, "Unrecognized option %s", argv[1]); error = true; diff --git a/lib/dpctl.h b/lib/dpctl.h index 9d0052152..b042663cc 100644 --- a/lib/dpctl.h +++ b/lib/dpctl.h @@ -42,6 +42,9 @@ struct dpctl_params { /* --names: Use port names in output? */ bool names; + /* --consistent: Install consistent flow. */ + bool consistent; + /* Callback for printing. This function is called from dpctl_run_command() * to output data. The 'aux' parameter is set to the 'aux' * member. The 'error' parameter is true if 'string' is an error diff --git a/lib/odp-util.c b/lib/odp-util.c index 252a91bfa..ddf30077c 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -6592,6 +6592,17 @@ odp_flow_key_hash(const void *key, size_t key_len, ovs_u128 *hash) } hash_bytes128(key, key_len, secret, hash); uuid_set_bits_v4((struct uuid *)hash); + + /* Clean up the first bit. */ + hash->u32[0] &= ~0x1; +} + +void +odp_flow_key_hash_local(const void *key, size_t key_len, ovs_u128 *hash) +{ + odp_flow_key_hash(key, key_len, hash); + /* If setting 1, it means flows are consistent. */ + hash->u32[0] |= 0x1; } static void diff --git a/lib/odp-util.h b/lib/odp-util.h index 623a66aa2..dc0ad2332 100644 --- a/lib/odp-util.h +++ b/lib/odp-util.h @@ -244,6 +244,7 @@ void odp_flow_key_from_flow(const struct odp_flow_key_parms *, struct ofpbuf *); void odp_flow_key_from_mask(const struct odp_flow_key_parms *, struct ofpbuf *); void odp_flow_key_hash(const void *key, size_t key_len, ovs_u128 *hash); +void odp_flow_key_hash_local(const void *key, size_t key_len, ovs_u128 *hash); /* Estimated space needed for metadata. */ enum { ODP_KEY_METADATA_SIZE = 9 * 8 }; diff --git a/lib/uuid.h b/lib/uuid.h index fa49354f6..1aab3231e 100644 --- a/lib/uuid.h +++ b/lib/uuid.h @@ -42,6 +42,9 @@ extern "C" { ((unsigned int) ((UUID)->parts[2] & 0xffff)), \ ((unsigned int) ((UUID)->parts[3])) +#define UUID_LOCAL(ufid) \ + (((ufid)->u32[0] & 0x1) == 0x1) + /* Returns a hash value for 'uuid'. This hash value is the same regardless of * whether we are running on a 32-bit or 64-bit or big-endian or little-endian * architecture. */ diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 19b92dfe0..c8ea16c18 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -2685,6 +2685,10 @@ revalidate(struct revalidator *revalidator) bool already_dumped; int error; + if (f->ufid_present && UUID_LOCAL(&(f)->ufid)) { + continue; + } + if (ukey_acquire(udpif, f, &ukey, &error)) { if (error == EBUSY) { /* Another thread is processing this flow, so don't bother @@ -2794,6 +2798,9 @@ revalidator_sweep__(struct revalidator *revalidator, bool purge) CMAP_FOR_EACH(ukey, cmap_node, &umap->cmap) { enum ukey_state ukey_state; + if (ukey->ufid_present && UUID_LOCAL(&(ukey)->ufid)) { + continue; + } /* Handler threads could be holding a ukey lock while it installs a * new flow, so don't hang around waiting for access to it. */ if (ovs_mutex_trylock(&ukey->mutex)) { From patchwork Mon Dec 14 02:20:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tonghao Zhang X-Patchwork-Id: 1415730 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=nKq+9xiW; dkim-atps=neutral Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CvQCf6LjQz9sTX for ; Mon, 14 Dec 2020 13:22:54 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 316EA2048B; Mon, 14 Dec 2020 02:22:52 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9A5hZii1EqT7; Mon, 14 Dec 2020 02:22:32 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 12DD52047B; Mon, 14 Dec 2020 02:22:25 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 06436C1833; Mon, 14 Dec 2020 02:22:25 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id F2AFBC013B for ; Mon, 14 Dec 2020 02:22:23 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id E69F787273 for ; Mon, 14 Dec 2020 02:22:23 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5nsakwdE4+H2 for ; Mon, 14 Dec 2020 02:22:22 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f193.google.com (mail-pg1-f193.google.com [209.85.215.193]) by hemlock.osuosl.org (Postfix) with ESMTPS id 7806287208 for ; Mon, 14 Dec 2020 02:22:22 +0000 (UTC) Received: by mail-pg1-f193.google.com with SMTP id n7so11492899pgg.2 for ; Sun, 13 Dec 2020 18:22:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qgc9bs0CachPnhvJ3EchkOohnw7o7jmQpEe5Y/L5bIQ=; b=nKq+9xiW76nLvgaTZCpTDPC4z9UslLRJCYhOBLNyAR036k6AjsnSg2yLA/GoXtKnax FF8lQaJctkEHGrUSDOXl5eJ6lDJMjykSWhiYWX+5x53pvzgcW2U5GoUECyhE0xFRiTN2 7ucb9O8tLinLRXsMuD0/SvdItQW1UkNOG4aAT04cms95nHJwFkGTI3iUVAkPnvWf5wma cEebSRaFwbqp8A01sAuSmpB29U17tcoRwqiOf4v4xDtXYgphHy3jMM1ccq4OS6NKtd3/ JiWPynZsOxqq3i5sd4KLFlGvi5DcIu5FkFWzj82HDJe2mffO5zs1bDEyLwQ4NCQLedUa Ozhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qgc9bs0CachPnhvJ3EchkOohnw7o7jmQpEe5Y/L5bIQ=; b=Bg7Glc6JWzXvo+hv1hlPAPWsyzRBy84b2H9ZfeWPMl5FzaTPf/c/MTsIdshweDgokt zxbMd8bfpAyiRSlL/bQf7EQ1lTyhPcdg6Ta+HuF1wLqbGCJ4T3cvyQpGVODyGL+GcrEh dlk+ZwDasSeFhYkleIKr4TuzfXgwsEkZ2sfwzrNMU0fgus7lKZz4jZsLi+L4kCqhFvHH NNMwd1/L3g4mWvq33urPgbK3hy9oRhIx+pW7hiWaClNUjtJiQjsD/ZMmt3m+SRQ2qBuJ w7U6s9AkHx6Noc5jws3riGedsKMfKuYKQ7vej2fqpHnpub0sXUrr+GRf5QS1iYok6bhP 3PpQ== X-Gm-Message-State: AOAM533FpRndeet+bBWL9aaNdSLqloP5ByfCX0y9R5UgsOgqFtwepzHe fi3BCTagnQAm+hx9XqnpWhQ= X-Google-Smtp-Source: ABdhPJxn0kQf2emndkrJxKdx9De07QvS2nvx51n9q5w+H/upbd/Q9GAFFiX/xQgqukzhu9oJea1VFQ== X-Received: by 2002:a63:c20e:: with SMTP id b14mr2984449pgd.363.1607912542105; Sun, 13 Dec 2020 18:22:22 -0800 (PST) Received: from localhost.localdomain ([50.236.19.102]) by smtp.gmail.com with ESMTPSA id z7sm18019540pfq.193.2020.12.13.18.22.16 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 13 Dec 2020 18:22:21 -0800 (PST) From: xiangxia.m.yue@gmail.com To: blp@ovn.org, i.maximets@ovn.org, u9012063@gmail.com, elibr@nvidia.com Date: Mon, 14 Dec 2020 10:20:00 +0800 Message-Id: <20201214022001.84273-4-xiangxia.m.yue@gmail.com> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20201214022001.84273-1-xiangxia.m.yue@gmail.com> References: <20201214022001.84273-1-xiangxia.m.yue@gmail.com> Cc: dev@openvswitch.org Subject: [ovs-dev] [PATCH ovs v1 3/4] tnl-neigh-cache: Allow openvswitch learning neigh entries. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Tonghao Zhang In flow bifurcation case, in the system there is only one IP address, for example, IPv4 address. We assign it to PF netdevice, but not openvswitch bridge. We hope steering the tunnel packets to openvswitch from PF and building tunnel packets. When buiding the tunnel packets, openvswitch can use the neigh entries learned from system. Signed-off-by: Tonghao Zhang --- lib/dpif-netdev.c | 1 + lib/tnl-neigh-cache.c | 312 +++++++++++++++++++++++++++++++++++++++++++++++--- lib/tnl-neigh-cache.h | 2 + vswitchd/bridge.c | 2 + vswitchd/vswitch.xml | 17 +++ 5 files changed, 321 insertions(+), 13 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 300861ca5..edc4122af 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -5804,6 +5804,7 @@ dpif_netdev_wait(struct dpif *dpif) ovs_mutex_unlock(&dp->port_mutex); ovs_mutex_unlock(&dp_netdev_mutex); seq_wait(tnl_conf_seq, dp->last_tnl_conf_seq); + tnl_neigh_cache_wait(); } static void diff --git a/lib/tnl-neigh-cache.c b/lib/tnl-neigh-cache.c index 5bda4af7e..8f346ba78 100644 --- a/lib/tnl-neigh-cache.c +++ b/lib/tnl-neigh-cache.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include "bitmap.h" @@ -35,6 +37,7 @@ #include "ovs-thread.h" #include "packets.h" #include "openvswitch/poll-loop.h" +#include "openvswitch/ofpbuf.h" #include "seq.h" #include "socket-util.h" #include "timeval.h" @@ -42,10 +45,16 @@ #include "unixctl.h" #include "util.h" #include "openvswitch/vlog.h" +#include "netlink-notifier.h" +#include "netlink-socket.h" +#include "netlink.h" +#include "smap.h" +VLOG_DEFINE_THIS_MODULE(tnl_neigh_cache); /* In seconds */ #define NEIGH_ENTRY_DEFAULT_IDLE_TIME (15 * 60) +#define NUD_VALID (NUD_PERMANENT|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY) struct tnl_neigh_entry { struct cmap_node cmap_node; @@ -53,10 +62,30 @@ struct tnl_neigh_entry { struct eth_addr mac; time_t expires; /* Expiration time. */ char br_name[IFNAMSIZ]; + bool event; }; +enum tnl_neigh_nlmsg_op { + TNL_NEIGH_NLMSG_ADD = 1, + TNL_NEIGH_NLMSG_DEL, +}; + +struct tnl_neigh_nlmsg { + struct in6_addr ip; + struct eth_addr mac; + char br_name[IFNAMSIZ]; + enum tnl_neigh_nlmsg_op op; +}; + +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); static struct cmap table = CMAP_INITIALIZER; static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; +static struct nln_notifier *neigh_notifier = NULL; +static struct nln *neigh_nln = NULL; +static struct tnl_neigh_nlmsg tnmsg; + +static int tnl_neigh_event_parse(struct ofpbuf *, struct tnl_neigh_nlmsg *); +static void tnl_neigh_event_change(const struct tnl_neigh_nlmsg *, void *); static uint32_t tnl_neigh_hash(const struct in6_addr *ip) @@ -72,7 +101,8 @@ tnl_neigh_lookup__(const char br_name[IFNAMSIZ], const struct in6_addr *dst) hash = tnl_neigh_hash(dst); CMAP_FOR_EACH_WITH_HASH (neigh, cmap_node, hash, &table) { - if (ipv6_addr_equals(&neigh->ip, dst) && !strcmp(neigh->br_name, br_name)) { + if (ipv6_addr_equals(&neigh->ip, dst) && + !strcmp(neigh->br_name, br_name) && !neigh->event) { if (neigh->expires <= time_now()) { return NULL; } @@ -81,6 +111,15 @@ tnl_neigh_lookup__(const char br_name[IFNAMSIZ], const struct in6_addr *dst) return neigh; } } + + /* To check whether neigh entry available which learned from system. */ + CMAP_FOR_EACH_WITH_HASH (neigh, cmap_node, hash, &table) { + if (ipv6_addr_equals(&neigh->ip, dst) && + neigh->event) { + return neigh; + } + } + return NULL; } @@ -114,15 +153,13 @@ tnl_neigh_delete(struct tnl_neigh_entry *neigh) } static void -tnl_neigh_set__(const char name[IFNAMSIZ], const struct in6_addr *dst, - const struct eth_addr mac) +tnl_neigh_set_nolock(const char name[IFNAMSIZ], const struct in6_addr *dst, + const struct eth_addr mac, bool event) { - ovs_mutex_lock(&mutex); struct tnl_neigh_entry *neigh = tnl_neigh_lookup__(name, dst); if (neigh) { if (eth_addr_equals(neigh->mac, mac)) { neigh->expires = time_now() + NEIGH_ENTRY_DEFAULT_IDLE_TIME; - ovs_mutex_unlock(&mutex); return; } tnl_neigh_delete(neigh); @@ -130,12 +167,39 @@ tnl_neigh_set__(const char name[IFNAMSIZ], const struct in6_addr *dst, seq_change(tnl_conf_seq); neigh = xmalloc(sizeof *neigh); - neigh->ip = *dst; neigh->mac = mac; + neigh->event = event; neigh->expires = time_now() + NEIGH_ENTRY_DEFAULT_IDLE_TIME; ovs_strlcpy(neigh->br_name, name, sizeof neigh->br_name); cmap_insert(&table, &neigh->cmap_node, tnl_neigh_hash(&neigh->ip)); +} + +static void +tnl_neigh_unset_nolock(const char name[IFNAMSIZ], const struct in6_addr *dst) +{ + struct tnl_neigh_entry *neigh; + bool changed = false; + + CMAP_FOR_EACH (neigh, cmap_node, &table) { + if (!strcmp(neigh->br_name, name) && + ipv6_addr_equals(&neigh->ip, dst) && neigh->event) { + tnl_neigh_delete(neigh); + changed = true; + } + } + + if (changed) { + seq_change(tnl_conf_seq); + } +} + +static void +tnl_neigh_set__(const char name[IFNAMSIZ], const struct in6_addr *dst, + const struct eth_addr mac) +{ + ovs_mutex_lock(&mutex); + tnl_neigh_set_nolock(name, dst, mac, false); ovs_mutex_unlock(&mutex); } @@ -208,11 +272,16 @@ tnl_neigh_cache_run(void) ovs_mutex_lock(&mutex); CMAP_FOR_EACH(neigh, cmap_node, &table) { - if (neigh->expires <= time_now()) { + if (!neigh->event && neigh->expires <= time_now()) { tnl_neigh_delete(neigh); changed = true; } } + + if (neigh_nln) { + nln_run(neigh_nln); + } + ovs_mutex_unlock(&mutex); if (changed) { @@ -220,6 +289,16 @@ tnl_neigh_cache_run(void) } } +void +tnl_neigh_cache_wait(void) +{ + ovs_mutex_lock(&mutex); + if (neigh_nln) { + nln_wait(neigh_nln); + } + ovs_mutex_unlock(&mutex); +} + void tnl_neigh_flush(const char br_name[IFNAMSIZ]) { @@ -241,21 +320,29 @@ tnl_neigh_flush(const char br_name[IFNAMSIZ]) } static void -tnl_neigh_cache_flush(struct unixctl_conn *conn, int argc OVS_UNUSED, - const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) +tnl_neigh_flush__(bool event) { struct tnl_neigh_entry *neigh; bool changed = false; ovs_mutex_lock(&mutex); - CMAP_FOR_EACH(neigh, cmap_node, &table) { - tnl_neigh_delete(neigh); - changed = true; + CMAP_FOR_EACH (neigh, cmap_node, &table) { + if (!event || neigh->event) { + tnl_neigh_delete(neigh); + changed = true; + } } ovs_mutex_unlock(&mutex); if (changed) { seq_change(tnl_conf_seq); } +} + +static void +tnl_neigh_cache_flush(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) +{ + tnl_neigh_flush__(false); unixctl_command_reply(conn, "OK"); } @@ -319,7 +406,7 @@ tnl_neigh_cache_show(struct unixctl_conn *conn, int argc OVS_UNUSED, ds_put_format(&ds, ETH_ADDR_FMT" %s", ETH_ADDR_ARGS(neigh->mac), neigh->br_name); - if (neigh->expires <= time_now()) { + if (!neigh->event && neigh->expires <= time_now()) { ds_put_format(&ds, " STALE"); } ds_put_char(&ds, '\n'); @@ -330,6 +417,205 @@ tnl_neigh_cache_show(struct unixctl_conn *conn, int argc OVS_UNUSED, ds_destroy(&ds); } +static int +tnl_neigh_event_parse(struct ofpbuf *buf, struct tnl_neigh_nlmsg *change) +{ + static const struct nl_policy policy[] = { + [NDA_DST] = { .type = NL_A_UNSPEC, + .min_len = sizeof(struct in_addr), + .optional = false, }, + [NDA_LLADDR] = { .type = NL_A_UNSPEC, + .min_len = ETH_ALEN, + .optional = true, }, + }; + + struct nlattr *attrs[ARRAY_SIZE(policy)]; + const struct nlmsghdr *nlmsg = buf->data; + const struct ndmsg *ndm; + char namebuf[IFNAMSIZ]; + bool parsed; + struct in6_addr addr; + + /* Process RTM_NEWNEIGH or RTM_DELNEIGH events only. */ + if (nlmsg->nlmsg_type != RTM_NEWNEIGH && + nlmsg->nlmsg_type != RTM_DELNEIGH) { + return 0; + } + + ndm = ofpbuf_at(buf, NLMSG_HDRLEN, sizeof *ndm); + if (ndm->ndm_family != AF_INET && + ndm->ndm_family != AF_INET6) { + return 0; + } + + parsed = nl_policy_parse(buf, NLMSG_HDRLEN + sizeof(struct rtmsg), + policy, attrs, ARRAY_SIZE(policy)); + if (!parsed) { + VLOG_DBG_RL(&rl, "The tnl neigh event parse failed"); + return 0; + } + + if (!if_indextoname(ndm->ndm_ifindex, namebuf)) { + return 0; + } + + memset(change, 0, sizeof *change); + ovs_strlcpy(change->br_name, namebuf, sizeof change->br_name); + + if (ndm->ndm_family == AF_INET) { + const ovs_be32 *ip4; + ip4 = nl_attr_get_unspec(attrs[NDA_DST], sizeof *ip4); + addr = in6_addr_mapped_ipv4(*ip4); + } else { + const struct in6_addr *ip6; + ip6 = nl_attr_get_unspec(attrs[NDA_DST], sizeof *ip6); + addr = *ip6; + } + + change->ip = addr; + change->op = TNL_NEIGH_NLMSG_DEL; + if (nlmsg->nlmsg_type == RTM_NEWNEIGH) { + /* If neigh entry was not ready, will not cache it. */ + if (!(ndm->ndm_state & NUD_VALID) || !attrs[NDA_LLADDR]) { + return 0; + } + + const struct eth_addr *mac; + mac = nl_attr_get_unspec(attrs[NDA_LLADDR], ETH_ALEN); + change->mac = *mac; + change->op = TNL_NEIGH_NLMSG_ADD; + } + + return RTNLGRP_NEIGH; +} + +static void +tnl_neigh_event_change(const struct tnl_neigh_nlmsg *change, + void *aux OVS_UNUSED) +{ + if (!change) { + return; + } + + switch (change->op) { + case TNL_NEIGH_NLMSG_ADD: + VLOG_DBG("Add neigh entry: %s "ETH_ADDR_FMT, + change->br_name, ETH_ADDR_ARGS(change->mac)); + tnl_neigh_set_nolock(change->br_name, &change->ip, + change->mac, true); + break; + case TNL_NEIGH_NLMSG_DEL: + { + char ip[INET6_ADDRSTRLEN]; + + ipv6_string_mapped(ip, &change->ip); + VLOG_DBG("Del neigh entry: %s %s", change->br_name, ip); + tnl_neigh_unset_nolock(change->br_name, &change->ip); + break; + } + default: + VLOG_ERR_RL(&rl, "The message ops of neigh netlink is unknown"); + break; + } +} + +static void +tnl_neigh_event_uninit(void) +{ + if (neigh_notifier) { + nln_notifier_destroy(neigh_notifier); + neigh_notifier = NULL; + } + + if (neigh_nln) { + nln_destroy(neigh_nln); + neigh_nln = NULL; + } +} + +static int +tnl_neigh_event_init(void) +{ + neigh_nln = nln_create(NETLINK_ROUTE, + (nln_parse_func *) tnl_neigh_event_parse, + &tnmsg); + if (!neigh_nln) { + return -1; + } + + neigh_notifier = + nln_notifier_create(neigh_nln, RTNLGRP_NEIGH, + (nln_notify_func *) tnl_neigh_event_change, + NULL); + if (!neigh_notifier) { + tnl_neigh_event_uninit(); + return -1; + } + + return 0; +} + +static int +tnl_neigh_event_dump(void) +{ + uint64_t reply_stub[NL_DUMP_BUFSIZE / 8]; + struct ofpbuf request, reply, buf; + struct nl_dump dump; + struct ndmsg *ndmsg; + + ofpbuf_init(&request, 0); + nl_msg_put_nlmsghdr(&request, sizeof *ndmsg, RTM_GETNEIGH, + NLM_F_REQUEST | NLM_F_DUMP); + + ndmsg = ofpbuf_put_zeros(&request, sizeof *ndmsg); + ndmsg->ndm_family = AF_UNSPEC; + + nl_dump_start(&dump, NETLINK_ROUTE, &request); + ofpbuf_uninit(&request); + + ofpbuf_use_stub(&buf, reply_stub, sizeof reply_stub); + while (nl_dump_next(&dump, &reply, &buf)) { + struct tnl_neigh_nlmsg msg; + + if (tnl_neigh_event_parse(&reply, &msg)) { + tnl_neigh_event_change(&msg, NULL); + } + } + ofpbuf_uninit(&buf); + return nl_dump_done(&dump); +} + +void +tnl_neigh_event_enabled(const struct smap *ovs_other_config) +{ + int err; + + if (smap_get_bool(ovs_other_config, "tnl-neigh-event-enabled", false)) { + if (neigh_nln || neigh_notifier) { + return; + } + + err = tnl_neigh_event_init(); + if (err) { + VLOG_ERR("Can't create nln handle or notifier for neighboring subsystem"); + return; + } + + err = tnl_neigh_event_dump(); + if (err) { + tnl_neigh_event_uninit(); + VLOG_ERR("Can't dump neigh entries"); + return; + } + } else { + if (!neigh_nln && !neigh_notifier) { + return; + } + tnl_neigh_flush__(true); + tnl_neigh_event_uninit(); + } +} + void tnl_neigh_cache_init(void) { diff --git a/lib/tnl-neigh-cache.h b/lib/tnl-neigh-cache.h index ded9c2f86..f98743d06 100644 --- a/lib/tnl-neigh-cache.h +++ b/lib/tnl-neigh-cache.h @@ -37,6 +37,8 @@ int tnl_neigh_lookup(const char dev_name[], const struct in6_addr *dst, struct eth_addr *mac); void tnl_neigh_cache_init(void); void tnl_neigh_cache_run(void); +void tnl_neigh_cache_wait(void); void tnl_neigh_flush(const char dev_name[]); +void tnl_neigh_event_enabled(const struct smap *ovs_other_config); #endif diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 5ed7e8234..161bb5f8b 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -69,6 +69,7 @@ #include "util.h" #include "unixctl.h" #include "lib/vswitch-idl.h" +#include "tnl-neigh-cache.h" #include "xenserver.h" #include "vlan-bitmap.h" @@ -3292,6 +3293,7 @@ bridge_run(void) netdev_set_flow_api_enabled(&cfg->other_config); dpdk_init(&cfg->other_config); userspace_tso_init(&cfg->other_config); + tnl_neigh_event_enabled(&cfg->other_config); } /* Initialize the ofproto library. This only needs to run once, but diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 89a876796..b0f22b534 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -222,6 +222,23 @@

+ +

+ Set this value to true to enable learning neigh from system. + The default value is false. +

+

+ If enabled, Open vSwitch can learn the neigh entries from system. Then you + may not configure tunnel IP address on Open vSwitch bridge, + when encapsulating tunnel packets(e.g. native_tunnel_output), we try to use + the neigh entry which learned from system. That is useful for the flow bifurcation + that is a mechanism which uses hardware capable Ethernet devices + to split traffic between Linux user space and kernel space. More details: + http://git.dpdk.org/next/dpdk-next-net/tree/doc/guides/howto/flow_bifurcation.rst +

+
+

From patchwork Mon Dec 14 02:20:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tonghao Zhang X-Patchwork-Id: 1415731 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=rrqWhNcZ; dkim-atps=neutral Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CvQCn0Y9bz9sTc for ; Mon, 14 Dec 2020 13:23:01 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 8A39A2047B; Mon, 14 Dec 2020 02:22:59 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Q-Jcbj7UG5fu; Mon, 14 Dec 2020 02:22:43 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 6AF7120498; Mon, 14 Dec 2020 02:22:28 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 23942C1833; Mon, 14 Dec 2020 02:22:28 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id CA702C088E for ; Mon, 14 Dec 2020 02:22:26 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id B92F385BF2 for ; Mon, 14 Dec 2020 02:22:26 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Vna28Vz3N9nv for ; Mon, 14 Dec 2020 02:22:26 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f195.google.com (mail-pg1-f195.google.com [209.85.215.195]) by fraxinus.osuosl.org (Postfix) with ESMTPS id 09F3F85A74 for ; Mon, 14 Dec 2020 02:22:26 +0000 (UTC) Received: by mail-pg1-f195.google.com with SMTP id n10so3451234pgl.10 for ; Sun, 13 Dec 2020 18:22:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TiyRHsBcNAmXi+1bMSyi1GARAIyD0JhRVloxU+Ey0dw=; b=rrqWhNcZxTSMJ00KcjaUvtmCO6+kowP+LtdGCXKGqbYnPOSg2S5KiWIghqZtfWS2+8 MhMnY3Xf0UhwcCeMkXvf95AZpPob1V3LRgPHoPZO39VGCWnWJwrUiOA7VbJ25a3+dwlJ DCHe0hfdFL9XyeeBQfim4SNmx9M669gr8vJWOkOoSpscvRvgNnepg76iX4qx/2AtfW6u 9X2Pmtfm1GdIJWAfZOZMLET6V3lQpKsZBTnnE6pUFudo49pRRtqM/xtD+h5LTdI7Ly9b VWcZWjPbGBUKMo8C5TK+dtD5UlH5VNQwRAtIsfD5l+GzYl+B4ueA4d/OxQ3n9EyqVPZb 4zqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TiyRHsBcNAmXi+1bMSyi1GARAIyD0JhRVloxU+Ey0dw=; b=PF+QLjZ4QZcf7LVgkRDHrn4UZWYNVjSANpSM1TXPor8NnEbSc/W0ukTeMUSBsSARke dZcUXho5sqoMFLqWaQ7OvDF9JQL45B0KRUrSUu+Ul2xQXV7ZYoZlozhVFJas9rZT1XXO ErBM6EkMVgP/NEsYknwCCSP7oIBH6tl/I1BI9KxwHhgcygPFgou5SBiYf2w9sT4D/RWJ KhAQH50yO0K0+SmVtoCiOUCK4EZGXlflMHrJxrB9LQLKJbwcNxI1iNEi5wpYbnmFdiEm +DLLFsyi7oDLKlw/DOr7mm+br4nYVwViTXb00WEq0btEZtNMKKb1MrfNBnr45q7fyhcM 5QkA== X-Gm-Message-State: AOAM531kgp00COD+t/jTjBki0rHPjSjGz9R1z1k+XCCvmVAdhucSw6yc eLAFMqwtgPByOfSV9WtQByk= X-Google-Smtp-Source: ABdhPJxZQkmW6yMyu6ANOdbkuLkU9fsRHqLHL96nyJY10NRjKMhTei5kCUcoE0OPgG1pqJJrCHmwiQ== X-Received: by 2002:aa7:8d19:0:b029:1a3:82bd:908a with SMTP id j25-20020aa78d190000b02901a382bd908amr7730293pfe.58.1607912545687; Sun, 13 Dec 2020 18:22:25 -0800 (PST) Received: from localhost.localdomain ([50.236.19.102]) by smtp.gmail.com with ESMTPSA id z7sm18019540pfq.193.2020.12.13.18.22.22 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 13 Dec 2020 18:22:25 -0800 (PST) From: xiangxia.m.yue@gmail.com To: blp@ovn.org, i.maximets@ovn.org, u9012063@gmail.com, elibr@nvidia.com Date: Mon, 14 Dec 2020 10:20:01 +0800 Message-Id: <20201214022001.84273-5-xiangxia.m.yue@gmail.com> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20201214022001.84273-1-xiangxia.m.yue@gmail.com> References: <20201214022001.84273-1-xiangxia.m.yue@gmail.com> Cc: dev@openvswitch.org Subject: [ovs-dev] [PATCH ovs v1 4/4] ovs-router: Allow openvswitch installing fake routes. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Tonghao Zhang Now we can only add route entries which are on the same subnet with openvswitch bridges. With this patch, users can add "fake" route entries to openvswich which can use them to encapsulate packets. Signed-off-by: Tonghao Zhang --- lib/ovs-router.c | 121 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 46 deletions(-) diff --git a/lib/ovs-router.c b/lib/ovs-router.c index 09b81c6e5..9cb9b3540 100644 --- a/lib/ovs-router.c +++ b/lib/ovs-router.c @@ -47,6 +47,9 @@ #include "unaligned.h" #include "openvswitch/vlog.h" +#define PRIO_USER(plen) ((plen) + 32) +#define PRIO_LOCAL(plen) ((plen) + 64) + VLOG_DEFINE_THIS_MODULE(ovs_router); static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); @@ -216,7 +219,8 @@ static int ovs_router_insert__(uint32_t mark, uint8_t priority, bool local, const struct in6_addr *ip6_dst, uint8_t plen, const char output_bridge[], - const struct in6_addr *gw) + const struct in6_addr *gw, + const struct in6_addr *ip6_src) { const struct cls_rule *cr; struct ovs_router_entry *p; @@ -235,19 +239,24 @@ ovs_router_insert__(uint32_t mark, uint8_t priority, bool local, p->plen = plen; p->local = local; p->priority = priority; - err = get_src_addr(ip6_dst, output_bridge, &p->src_addr); - if (err && ipv6_addr_is_set(gw)) { - err = get_src_addr(gw, output_bridge, &p->src_addr); + if (!ip6_src || !ipv6_addr_is_set(ip6_src)) { + err = get_src_addr(ip6_dst, output_bridge, &p->src_addr); + if (err && ipv6_addr_is_set(gw)) { + err = get_src_addr(gw, output_bridge, &p->src_addr); + } + if (err) { + struct ds ds = DS_EMPTY_INITIALIZER; + + ipv6_format_mapped(ip6_dst, &ds); + VLOG_DBG_RL(&rl, "src addr not available for route %s", ds_cstr(&ds)); + free(p); + ds_destroy(&ds); + return err; + } + } else { + p->src_addr = *ip6_src; } - if (err) { - struct ds ds = DS_EMPTY_INITIALIZER; - ipv6_format_mapped(ip6_dst, &ds); - VLOG_DBG_RL(&rl, "src addr not available for route %s", ds_cstr(&ds)); - free(p); - ds_destroy(&ds); - return err; - } /* Longest prefix matches first. */ cls_rule_init(&p->cr, &match, priority); @@ -270,8 +279,9 @@ ovs_router_insert(uint32_t mark, const struct in6_addr *ip_dst, uint8_t plen, const struct in6_addr *gw) { if (use_system_routing_table) { - uint8_t priority = local ? plen + 64 : plen; - ovs_router_insert__(mark, priority, local, ip_dst, plen, output_bridge, gw); + uint8_t priority = local ? PRIO_LOCAL(plen) : plen; + ovs_router_insert__(mark, priority, local, ip_dst, plen, + output_bridge, gw, NULL); } } @@ -338,48 +348,64 @@ static void ovs_router_add(struct unixctl_conn *conn, int argc, const char *argv[], void *aux OVS_UNUSED) { + struct in6_addr src6 = in6addr_any; struct in6_addr gw6 = in6addr_any; struct in6_addr ip6; - uint32_t mark = 0; - unsigned int plen; + ovs_be32 src = 0; + ovs_be32 gw = 0; ovs_be32 ip; + bool ipv4_route_entry = true; + bool ipv4_local = false; + uint32_t lastargc = 0; + uint32_t mark = 0; + uint32_t plen; int err; - if (scan_ipv4_route(argv[1], &ip, &plen)) { - ovs_be32 gw = 0; + if (!scan_ipv4_route(argv[1], &ip, &plen)) { + if (!scan_ipv6_route(argv[1], &ip6, &plen)) { + unixctl_command_reply_error(conn, "Invalid parameters"); + return; + } + ipv4_route_entry = false; + } - if (argc > 3) { - if (!ovs_scan(argv[3], "pkt_mark=%"SCNi32, &mark) && - !ip_parse(argv[3], &gw)) { - unixctl_command_reply_error(conn, "Invalid pkt_mark or gateway"); - return; - } + while (argc > 3 && lastargc != argc) { + lastargc = argc; + + if (!strncmp(argv[argc - 1], "pkt_mark=", 9)) { + err = !ovs_scan(argv[--argc] + 9, "pkt_mark=%"SCNi32, &mark); + } else if (!strncmp(argv[argc - 1], "src_addr=", 9)) { + err = ipv4_route_entry ? + !ip_parse(argv[--argc] + 9, &src) : + !ipv6_parse(argv[--argc] + 9, &src6); + } else { + err = ipv4_route_entry ? + !ip_parse(argv[--argc], &gw) : + !ipv6_parse(argv[--argc], &gw6); + } + + if (err) { + unixctl_command_reply_error(conn, "Invalid pkt_mark, src_addr or gateway"); + return; } + } + + if (ipv4_route_entry) { in6_addr_set_mapped_ipv4(&ip6, ip); if (gw) { in6_addr_set_mapped_ipv4(&gw6, gw); } - plen += 96; - } else if (scan_ipv6_route(argv[1], &ip6, &plen)) { - if (argc > 3) { - if (!ovs_scan(argv[3], "pkt_mark=%"SCNi32, &mark) && - !ipv6_parse(argv[3], &gw6)) { - unixctl_command_reply_error(conn, "Invalid pkt_mark or IPv6 gateway"); - return; - } + if (src) { + in6_addr_set_mapped_ipv4(&src6, src); } - } else { - unixctl_command_reply_error(conn, "Invalid parameters"); - return; - } - if (argc > 4) { - if (!ovs_scan(argv[4], "pkt_mark=%"SCNi32, &mark)) { - unixctl_command_reply_error(conn, "Invalid pkt_mark"); - return; + if (plen == 32) { + ipv4_local = true; } + plen += 96; } - err = ovs_router_insert__(mark, plen + 32, false, &ip6, plen, argv[2], &gw6); + err = ovs_router_insert__(mark, PRIO_USER(plen), ipv4_local, &ip6, plen, + argv[2], &gw6, &src6); if (err) { unixctl_command_reply_error(conn, "Error while inserting route."); } else { @@ -410,7 +436,7 @@ ovs_router_del(struct unixctl_conn *conn, int argc OVS_UNUSED, } } - if (rt_entry_delete(mark, plen + 32, &ip6, plen)) { + if (rt_entry_delete(mark, PRIO_USER(plen), &ip6, plen)) { unixctl_command_reply(conn, "OK"); seq_change(tnl_conf_seq); } else { @@ -428,7 +454,8 @@ ovs_router_show(struct unixctl_conn *conn, int argc OVS_UNUSED, ds_put_format(&ds, "Route Table:\n"); CLS_FOR_EACH(rt, cr, &cls) { uint8_t plen; - if (rt->priority == rt->plen || rt->local) { + if (rt->priority == rt->plen || + (rt->local && rt->priority == PRIO_LOCAL(rt->plen))) { ds_put_format(&ds, "Cached: "); } else { ds_put_format(&ds, "User: "); @@ -505,7 +532,8 @@ ovs_router_flush(void) ovs_mutex_lock(&mutex); classifier_defer(&cls); CLS_FOR_EACH(rt, cr, &cls) { - if (rt->priority == rt->plen || rt->local) { + if (rt->priority == rt->plen || + (rt->local && rt->priority == PRIO_LOCAL(rt->plen))) { rt_entry_delete__(&rt->cr); } } @@ -530,8 +558,9 @@ ovs_router_init(void) classifier_init(&cls, NULL); unixctl_command_register("ovs/route/add", "ip_addr/prefix_len out_br_name [gw] " - "[pkt_mark=mark]", - 2, 4, ovs_router_add, NULL); + "[pkt_mark=mark]" + "[src_addr=src]", + 2, 5, ovs_router_add, NULL); unixctl_command_register("ovs/route/show", "", 0, 0, ovs_router_show, NULL); unixctl_command_register("ovs/route/del", "ip_addr/prefix_len "