From patchwork Mon Aug 16 21:15:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladislav Odintsov X-Patchwork-Id: 1517342 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=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) 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=RUetAZd9; dkim-atps=neutral Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GpRlV1GVcz9sRK for ; Tue, 17 Aug 2021 07:15:33 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 37FC2607D9; Mon, 16 Aug 2021 21:15:30 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id X2sjF1YkxYAs; Mon, 16 Aug 2021 21:15:25 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTPS id 9B833605A8; Mon, 16 Aug 2021 21:15:24 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 683A2C001D; Mon, 16 Aug 2021 21:15:24 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2FBD7C001A for ; Mon, 16 Aug 2021 21:15:23 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 1D58160795 for ; Mon, 16 Aug 2021 21:15:23 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4WQcNGjuPzI0 for ; Mon, 16 Aug 2021 21:15:18 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.8.0 Received: from mail-ed1-x531.google.com (mail-ed1-x531.google.com [IPv6:2a00:1450:4864:20::531]) by smtp3.osuosl.org (Postfix) with ESMTPS id 0F1EB605A8 for ; Mon, 16 Aug 2021 21:15:17 +0000 (UTC) Received: by mail-ed1-x531.google.com with SMTP id cn28so16613092edb.6 for ; Mon, 16 Aug 2021 14:15:17 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=uEvJfvTQtIwPnU0h3PNyipPbQ4d37jEut8n/NriEM0I=; b=RUetAZd9/XgAk8LyIMqqI4v6fFdzlTr1BYY9L5Au+nDiwCrXEhnSoBHxdNaIhJ65VE qqGlD1eK/k7pfP3Sb/6XgRFOCoAoXBfo+FhGiYUXA4WDBbON9Bpoc9JICABBOqp3NQCH 7XwoP0hWC9OTBigDTzPLunQyAfpz2x7E/kOLX0LF8ZrE0LWgzQh+cDqL0qPZgTe7rr3h 8qfqEQYMSuSPNKtrJTi33rqCWFYGlbn8hGqV8RiAXcI5X8O34DQY6rIiMyxK+h/aTxdu XJ2jWLOG3a3upxMtU/gVAriywsC8yW+OBmlDl4+Jjr9fmvM2hxgicrdrVEl8xcqmikAB MKhA== 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:mime-version:content-transfer-encoding; bh=uEvJfvTQtIwPnU0h3PNyipPbQ4d37jEut8n/NriEM0I=; b=c0aPJOcenQ4sUMrtTwI+Ob5AGy2+qKD2R9gomohj3gRw6OsCvu0ZrQSS1YziJ4GJAC gAURY2No8pPnFbshXqDlzPfFLJ5mxGhp5StCh09GDUSpM957/Y+0otvqhNPmrAwYvtLu fTbs0Rcjeut7y8mkO132CJ0Z86GMTGL6vqnLov0MK63H9a96ALRniuBR01NAi47n650G XjB5LpjExnYTVVR5bJa5jSYO9dCApvfOt1CVHDLhTCOuL9dM9U21zfLrkeavzzs2/X7M ldolfc7He1DO87ipJ5QxFKa6gKnHQfBOaaSAhZz4rqJIGDmR9WKdktT6a4qBJeM6rht/ L10g== X-Gm-Message-State: AOAM532UjWlYFKtlloHJD6Wtr1coWIZdpkTzTUHUY43+R5ekYVj0aSZt RhyE3/kd/HD7CBV/XP15AvlMWztLStw= X-Google-Smtp-Source: ABdhPJyqnMRl8XH560Yrq5N8LLVBVEdYpP5mEUwBbWdT5Cvy2xv5mNM5sPQrGwkbBaQTuoILHuzjKw== X-Received: by 2002:aa7:db95:: with SMTP id u21mr175763edt.152.1629148515589; Mon, 16 Aug 2021 14:15:15 -0700 (PDT) Received: from localhost.localdomain ([85.187.18.107]) by smtp.gmail.com with ESMTPSA id j29sm147890ejo.10.2021.08.16.14.15.14 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Aug 2021 14:15:15 -0700 (PDT) From: Vladislav Odintsov To: dev@openvswitch.org Date: Tue, 17 Aug 2021 00:15:05 +0300 Message-Id: <20210816211507.40325-2-odivlad@gmail.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210816211507.40325-1-odivlad@gmail.com> References: <20210816211507.40325-1-odivlad@gmail.com> MIME-Version: 1.0 Cc: Vladislav Odintsov Subject: [ovs-dev] [PATCH ovn 1/3] tests: remove strict check for table=N for N > 9 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: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Some tests which check logical flows were checking exact match for output. E.g.: table=12(lr_in_ip_routing ) ... This makes harder to add new tables in LR pipeline since in this case one have to update test, which are not relevant for the change. Replace all table=NN invocations with table=?? and update AT_CHECK command for it. This change is relevant for lrouter ingress pipeline table=N where N > 9, as next patches in this series will modify 10th table. Signed-off-by: Vladislav Odintsov --- tests/ovn-northd.at | 200 ++++++++++++++++++++++---------------------- tests/ovn.at | 26 +++--- 2 files changed, 113 insertions(+), 113 deletions(-) diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 190f78261..5f41112bc 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -2586,12 +2586,12 @@ Routing Policies ovn-sbctl dump-flows lr0 > lr0flows3 AT_CAPTURE_FILE([lr0flows3]) -AT_CHECK([grep "lr_in_policy" lr0flows3 | sort], [0], [dnl - table=12(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = 0; next;) - table=12(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.3), action=(reg8[[0..15]] = 1; reg8[[16..31]] = select(1, 2);) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == 0), action=(next;) +AT_CHECK([grep "lr_in_policy" lr0flows3 | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = 0; next;) + table=??(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.3), action=(reg8[[0..15]] = 1; reg8[[16..31]] = select(1, 2);) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == 0), action=(next;) ]) check ovn-nbctl --wait=sb lr-policy-add lr0 10 "ip4.src == 10.0.0.4" reroute 172.168.0.101,172.168.0.102,172.168.0.103 @@ -2600,16 +2600,16 @@ AT_CAPTURE_FILE([lr0flows3]) AT_CHECK([grep "lr_in_policy" lr0flows3 | \ sed 's/reg8\[[0..15\]] = [[0-9]]*/reg8\[[0..15\]] = /' | \ -sed 's/reg8\[[0..15\]] == [[0-9]]*/reg8\[[0..15\]] == /' | sort], [0], [dnl - table=12(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = ; next;) - table=12(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.3), action=(reg8[[0..15]] = ; reg8[[16..31]] = select(1, 2);) - table=12(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.4), action=(reg8[[0..15]] = ; reg8[[16..31]] = select(1, 2, 3);) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 3), action=(reg0 = 172.168.0.103; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == ), action=(next;) +sed 's/reg8\[[0..15\]] == [[0-9]]*/reg8\[[0..15\]] == /' | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = ; next;) + table=??(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.3), action=(reg8[[0..15]] = ; reg8[[16..31]] = select(1, 2);) + table=??(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.4), action=(reg8[[0..15]] = ; reg8[[16..31]] = select(1, 2, 3);) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 3), action=(reg0 = 172.168.0.103; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == ), action=(next;) ]) check ovn-nbctl --wait=sb lr-policy-add lr0 10 "ip4.src == 10.0.0.5" reroute 172.168.0.110 @@ -2618,17 +2618,17 @@ AT_CAPTURE_FILE([lr0flows3]) AT_CHECK([grep "lr_in_policy" lr0flows3 | \ sed 's/reg8\[[0..15\]] = [[0-9]]*/reg8\[[0..15\]] = /' | \ -sed 's/reg8\[[0..15\]] == [[0-9]]*/reg8\[[0..15\]] == /' | sort], [0], [dnl - table=12(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = ; next;) - table=12(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.3), action=(reg8[[0..15]] = ; reg8[[16..31]] = select(1, 2);) - table=12(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.4), action=(reg8[[0..15]] = ; reg8[[16..31]] = select(1, 2, 3);) - table=12(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.5), action=(reg0 = 172.168.0.110; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg8[[0..15]] = ; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 3), action=(reg0 = 172.168.0.103; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == ), action=(next;) +sed 's/reg8\[[0..15\]] == [[0-9]]*/reg8\[[0..15\]] == /' | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = ; next;) + table=??(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.3), action=(reg8[[0..15]] = ; reg8[[16..31]] = select(1, 2);) + table=??(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.4), action=(reg8[[0..15]] = ; reg8[[16..31]] = select(1, 2, 3);) + table=??(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.5), action=(reg0 = 172.168.0.110; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg8[[0..15]] = ; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 3), action=(reg0 = 172.168.0.103; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == ), action=(next;) ]) check ovn-nbctl --wait=sb lr-policy-del lr0 10 "ip4.src == 10.0.0.3" @@ -2637,14 +2637,14 @@ AT_CAPTURE_FILE([lr0flows3]) AT_CHECK([grep "lr_in_policy" lr0flows3 | \ sed 's/reg8\[[0..15\]] = [[0-9]]*/reg8\[[0..15\]] = /' | \ -sed 's/reg8\[[0..15\]] == [[0-9]]*/reg8\[[0..15\]] == /' | sort], [0], [dnl - table=12(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = ; next;) - table=12(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.4), action=(reg8[[0..15]] = ; reg8[[16..31]] = select(1, 2, 3);) - table=12(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.5), action=(reg0 = 172.168.0.110; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg8[[0..15]] = ; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 3), action=(reg0 = 172.168.0.103; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) - table=13(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == ), action=(next;) +sed 's/reg8\[[0..15\]] == [[0-9]]*/reg8\[[0..15\]] == /' | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = ; next;) + table=??(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.4), action=(reg8[[0..15]] = ; reg8[[16..31]] = select(1, 2, 3);) + table=??(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.5), action=(reg0 = 172.168.0.110; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg8[[0..15]] = ; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 1), action=(reg0 = 172.168.0.101; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 2), action=(reg0 = 172.168.0.102; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=100 , match=(reg8[[0..15]] == && reg8[[16..31]] == 3), action=(reg0 = 172.168.0.103; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; next;) + table=??(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == ), action=(next;) ]) check ovn-nbctl --wait=sb lr-policy-del lr0 10 "ip4.src == 10.0.0.4" @@ -2653,10 +2653,10 @@ AT_CAPTURE_FILE([lr0flows3]) AT_CHECK([grep "lr_in_policy" lr0flows3 | \ sed 's/reg8\[[0..15\]] = [[0-9]]*/reg8\[[0..15\]] = /' | \ -sed 's/reg8\[[0..15\]] == [[0-9]]*/reg8\[[0..15\]] == /' | sort], [0], [dnl - table=12(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = ; next;) - table=12(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.5), action=(reg0 = 172.168.0.110; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg8[[0..15]] = ; next;) - table=13(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == ), action=(next;) +sed 's/reg8\[[0..15\]] == [[0-9]]*/reg8\[[0..15\]] == /' | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = ; next;) + table=??(lr_in_policy ), priority=10 , match=(ip4.src == 10.0.0.5), action=(reg0 = 172.168.0.110; reg1 = 172.168.0.100; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; flags.loopback = 1; reg8[[0..15]] = ; next;) + table=??(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == ), action=(next;) ]) check ovn-nbctl --wait=sb add logical_router_policy . nexthops "2000\:\:b" @@ -2665,9 +2665,9 @@ AT_CAPTURE_FILE([lr0flows3]) AT_CHECK([grep "lr_in_policy" lr0flows3 | \ sed 's/reg8\[[0..15\]] = [[0-9]]*/reg8\[[0..15\]] = /' | \ -sed 's/reg8\[[0..15\]] == [[0-9]]*/reg8\[[0..15\]] == /' | sort], [0], [dnl - table=12(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = ; next;) - table=13(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == ), action=(next;) +sed 's/reg8\[[0..15\]] == [[0-9]]*/reg8\[[0..15\]] == /' | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_policy ), priority=0 , match=(1), action=(reg8[[0..15]] = ; next;) + table=??(lr_in_policy_ecmp ), priority=150 , match=(reg8[[0..15]] == ), action=(next;) ]) AT_CLEANUP @@ -4948,9 +4948,9 @@ check ovn-nbctl --wait=sb lrp-set-gateway-chassis lr0-public ch1 ovn-sbctl dump-flows lr0 > lr0flows AT_CAPTURE_FILE([sw0flows]) -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [dnl - table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) - table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) +AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) + table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) ]) check ovn-nbctl --wait=sb set logical_router_port lr0-public options:gateway_mtu=1500 @@ -4958,14 +4958,14 @@ check ovn-nbctl --wait=sb set logical_router_port lr0-public options:gateway_mtu ovn-sbctl dump-flows lr0 > lr0flows AT_CAPTURE_FILE([sw0flows]) -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [dnl - table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) - table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) - table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) +AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) + table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) ]) AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl @@ -4989,14 +4989,14 @@ check ovn-nbctl --wait=sb set logical_router lr0 options:chassis=ch1 ovn-sbctl dump-flows lr0 > lr0flows AT_CAPTURE_FILE([sw0flows]) -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [dnl - table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) - table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) - table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) +AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) + table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) ]) AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl @@ -5017,19 +5017,19 @@ check ovn-nbctl --wait=sb set logical_router_port lr0-sw0 options:gateway_mtu=14 ovn-sbctl dump-flows lr0 > lr0flows AT_CAPTURE_FILE([sw0flows]) -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [dnl - table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) - table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) - table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) - table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip6.dst = ip6.src; ip6.src = fe80::200:20ff:fe20:1213; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=0); };) +AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) + table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip6.dst = ip6.src; ip6.src = fe80::200:20ff:fe20:1213; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=0); };) ]) AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl @@ -5053,14 +5053,14 @@ check ovn-nbctl --wait=sb clear logical_router_port lr0-public options ovn-sbctl dump-flows lr0 > lr0flows AT_CAPTURE_FILE([sw0flows]) -AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sort], [0], [dnl - table=15(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) - table=15(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) - table=16(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip6.dst = ip6.src; ip6.src = fe80::200:20ff:fe20:1213; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) - table=16(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=0); };) +AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) + table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip6.dst = ip6.src; ip6.src = fe80::200:20ff:fe20:1213; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) + table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=0); };) ]) AT_CLEANUP @@ -5087,33 +5087,33 @@ ovn-sbctl dump-flows lr0 > lr0flows AT_CHECK([grep -e "lr_in_ip_routing.*select" lr0flows |sort], [0], [dnl ]) -AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows |sort], [0], [dnl - table=11(lr_in_ip_routing_ecmp), priority=150 , match=(reg8[[0..15]] == 0), action=(next;) +AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed 's/table=../table=??/' |sort], [0], [dnl + table=??(lr_in_ip_routing_ecmp), priority=150 , match=(reg8[[0..15]] == 0), action=(next;) ]) check ovn-nbctl --wait=sb --ecmp-symmetric-reply lr-route-add lr0 1.0.0.1 192.168.0.20 ovn-sbctl dump-flows lr0 > lr0flows -AT_CHECK([grep -e "lr_in_ip_routing.*select" lr0flows |sort], [0], [dnl - table=10(lr_in_ip_routing ), priority=65 , match=(ip4.dst == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; reg8[[16..31]] = select(1, 2);) +AT_CHECK([grep -e "lr_in_ip_routing.*select" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_ip_routing ), priority=65 , match=(ip4.dst == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; reg8[[16..31]] = select(1, 2);) ]) -AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed 's/192\.168\.0\..0/192.168.0.??/' |sort], [0], [dnl - table=11(lr_in_ip_routing_ecmp), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 1), action=(reg0 = 192.168.0.??; reg1 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; next;) - table=11(lr_in_ip_routing_ecmp), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 2), action=(reg0 = 192.168.0.??; reg1 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; next;) - table=11(lr_in_ip_routing_ecmp), priority=150 , match=(reg8[[0..15]] == 0), action=(next;) +AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed 's/192\.168\.0\..0/192.168.0.??/' | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_ip_routing_ecmp), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 1), action=(reg0 = 192.168.0.??; reg1 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; next;) + table=??(lr_in_ip_routing_ecmp), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 2), action=(reg0 = 192.168.0.??; reg1 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; next;) + table=??(lr_in_ip_routing_ecmp), priority=150 , match=(reg8[[0..15]] == 0), action=(next;) ]) # add ecmp route with wrong nexthop check ovn-nbctl --wait=sb --ecmp-symmetric-reply lr-route-add lr0 1.0.0.1 192.168.1.20 ovn-sbctl dump-flows lr0 > lr0flows -AT_CHECK([grep -e "lr_in_ip_routing.*select" lr0flows |sort], [0], [dnl - table=10(lr_in_ip_routing ), priority=65 , match=(ip4.dst == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; reg8[[16..31]] = select(1, 2);) +AT_CHECK([grep -e "lr_in_ip_routing.*select" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_ip_routing ), priority=65 , match=(ip4.dst == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; reg8[[16..31]] = select(1, 2);) ]) -AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed 's/192\.168\.0\..0/192.168.0.??/' |sort], [0], [dnl - table=11(lr_in_ip_routing_ecmp), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 1), action=(reg0 = 192.168.0.??; reg1 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; next;) - table=11(lr_in_ip_routing_ecmp), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 2), action=(reg0 = 192.168.0.??; reg1 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; next;) - table=11(lr_in_ip_routing_ecmp), priority=150 , match=(reg8[[0..15]] == 0), action=(next;) +AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed 's/192\.168\.0\..0/192.168.0.??/' | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_ip_routing_ecmp), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 1), action=(reg0 = 192.168.0.??; reg1 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; next;) + table=??(lr_in_ip_routing_ecmp), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 2), action=(reg0 = 192.168.0.??; reg1 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; next;) + table=??(lr_in_ip_routing_ecmp), priority=150 , match=(reg8[[0..15]] == 0), action=(next;) ]) AT_CLEANUP @@ -5191,10 +5191,10 @@ AT_CHECK([grep lr_in_lookup_neighbor lrflows | grep cr-DR | sort], [0], [dnl table=1 (lr_in_lookup_neighbor), priority=100 , match=(inport == "DR-S3" && arp.spa == 172.16.3.0/24 && arp.op == 1 && is_chassis_resident("cr-DR-S3")), action=(reg9[[2]] = lookup_arp(inport, arp.spa, arp.sha); next;) ]) # Check the flows in lr_in_gw_redirect stage -AT_CHECK([grep lr_in_gw_redirect lrflows | grep cr-DR | sort], [0], [dnl - table=17(lr_in_gw_redirect ), priority=50 , match=(outport == "DR-S1"), action=(outport = "cr-DR-S1"; next;) - table=17(lr_in_gw_redirect ), priority=50 , match=(outport == "DR-S2"), action=(outport = "cr-DR-S2"; next;) - table=17(lr_in_gw_redirect ), priority=50 , match=(outport == "DR-S3"), action=(outport = "cr-DR-S3"; next;) +AT_CHECK([grep lr_in_gw_redirect lrflows | grep cr-DR | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_gw_redirect ), priority=50 , match=(outport == "DR-S1"), action=(outport = "cr-DR-S1"; next;) + table=??(lr_in_gw_redirect ), priority=50 , match=(outport == "DR-S2"), action=(outport = "cr-DR-S2"; next;) + table=??(lr_in_gw_redirect ), priority=50 , match=(outport == "DR-S3"), action=(outport = "cr-DR-S3"; next;) ]) AT_CLEANUP diff --git a/tests/ovn.at b/tests/ovn.at index 7144b35fe..8cd4edebe 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -17895,9 +17895,9 @@ wait_row_count nb:Logical_Switch_Port 1 up=false name=sw0-vir check ovn-nbctl --wait=hv sync # verify the traffic from virtual port is discarded if the port is not claimed -AT_CHECK([grep lr_in_gw_redirect lr0-flows2 | grep "ip4.src == 10.0.0.10"], [0], [dnl - table=17(lr_in_gw_redirect ), priority=100 , match=(ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("sw0-vir")), action=(eth.src = 10:54:00:00:00:10; reg1 = 172.168.0.50; next;) - table=17(lr_in_gw_redirect ), priority=80 , match=(ip4.src == 10.0.0.10 && outport == "lr0-public"), action=(drop;) +AT_CHECK([grep lr_in_gw_redirect lr0-flows2 | grep "ip4.src == 10.0.0.10" | sed 's/table=../table=??/'], [0], [dnl + table=??(lr_in_gw_redirect ), priority=100 , match=(ip4.src == 10.0.0.10 && outport == "lr0-public" && is_chassis_resident("sw0-vir")), action=(eth.src = 10:54:00:00:00:10; reg1 = 172.168.0.50; next;) + table=??(lr_in_gw_redirect ), priority=80 , match=(ip4.src == 10.0.0.10 && outport == "lr0-public"), action=(drop;) ]) eth_src=505400000003 @@ -23013,32 +23013,32 @@ AT_CHECK([ grep "n_packets=1" -c) ]) -AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_policy.*priority=1001" | sort], [0], [dnl - table=12(lr_in_policy ), priority=1001 , dnl +AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_policy.*priority=1001" | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_policy ), priority=1001 , dnl match=(ip6), action=(pkt.mark = 4294967295; reg8[[0..15]] = 0; next;) ]) ovn-nbctl --wait=hv set logical_router_policy $pol5 options:pkt_mark=-1 -AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_policy.*priority=1001" | sort], [0], [dnl - table=12(lr_in_policy ), priority=1001 , dnl +AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_policy.*priority=1001" | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_policy ), priority=1001 , dnl match=(ip6), action=(reg8[[0..15]] = 0; next;) ]) ovn-nbctl --wait=hv set logical_router_policy $pol5 options:pkt_mark=2147483648 -AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_policy.*priority=1001" | sort], [0], [dnl - table=12(lr_in_policy ), priority=1001 , dnl +AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_policy.*priority=1001" | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_policy ), priority=1001 , dnl match=(ip6), action=(pkt.mark = 2147483648; reg8[[0..15]] = 0; next;) ]) ovn-nbctl --wait=hv set logical_router_policy $pol5 options:pkt_mark=foo -AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_policy.*priority=1001" | sort], [0], [dnl - table=12(lr_in_policy ), priority=1001 , dnl +AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_policy.*priority=1001" | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_policy ), priority=1001 , dnl match=(ip6), action=(reg8[[0..15]] = 0; next;) ]) ovn-nbctl --wait=hv set logical_router_policy $pol5 options:pkt_mark=4294967296 -AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_policy.*priority=1001" | sort], [0], [dnl - table=12(lr_in_policy ), priority=1001 , dnl +AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_policy.*priority=1001" | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_policy ), priority=1001 , dnl match=(ip6), action=(reg8[[0..15]] = 0; next;) ]) From patchwork Mon Aug 16 21:15:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladislav Odintsov X-Patchwork-Id: 1517343 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=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) 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=Sxf8K/if; dkim-atps=neutral Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GpRlY29Hvz9sRK for ; Tue, 17 Aug 2021 07:15:36 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 497FE83529; Mon, 16 Aug 2021 21:15:33 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bvtE0dgMJGgJ; Mon, 16 Aug 2021 21:15:29 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id 49DC183466; Mon, 16 Aug 2021 21:15:26 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2F597C001D; Mon, 16 Aug 2021 21:15:26 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id B15EBC001A for ; Mon, 16 Aug 2021 21:15:25 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id A102840473 for ; Mon, 16 Aug 2021 21:15:25 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp4.osuosl.org (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id CyFydUZ04O97 for ; Mon, 16 Aug 2021 21:15:20 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.8.0 Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by smtp4.osuosl.org (Postfix) with ESMTPS id 39FEB403D7 for ; Mon, 16 Aug 2021 21:15:20 +0000 (UTC) Received: by mail-ej1-x62d.google.com with SMTP id d11so34305798eja.8 for ; Mon, 16 Aug 2021 14:15:20 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=cTArMEVd6QUbY4yarVbP7UebuiyQodAVsH/6rbMg9R4=; b=Sxf8K/if+Gndvb7N2qO0TQPtzXHTrv2w97Y/lMIwJvmpXMj6BiciEjjXYXwtzcqzK/ yXbB74nm8IotkMCpRbNpxMA10YVGmBRUf8SfJESgvGNqIYK0/hj2o0BgKKMbZh9/q9mT FuDlgfKxc31WMBX3H4KTGtu8/V8vx9dGEuzpizfjRPoN32lwV0fcgjaJxu9Iq8qc4hVB +eLi/YzydXbsvch7XRK9RJTwDKwcC//MU28aJbtMhhilf8fvdIOYJPJUsNwQRPzsFCzA 9ILMLTWEVla1GQ/hJetc8PWdBg2n7Zsf14E9jB8hY6oHJxatJwGGQXm5kpjX7QTHiA03 Td0w== 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:mime-version:content-transfer-encoding; bh=cTArMEVd6QUbY4yarVbP7UebuiyQodAVsH/6rbMg9R4=; b=fPORdfvJbTNp9hBi0EORICNKSVn3JP/i8dVA02OYg34URJUmQUK8yySTDvFDM1YKCR UEVoVp4Y0PbGOTTTVVpHQPg34qW4dkMbpfI20QRd8ELR6+r9jPXAwN90pTojl9s5BpWY SlYDlTDEL8dxW0nFWxE5r1RtH/Ic+C2t6brrnR5MorfyZ1IdGIstWg27f9/YBW4nT+X+ EMdfAqWIArEoYUj4EtwUVjPWcm/7eKN/iwUoO+gkQ7x+u32td3p1iC2l8Nap94n8eOaa bn0oORlnkQ2d7nztyLd08jZun0+tptaJmZfPFHP8R9UtAKdQJvK8oYtHojcUFahiGuCK Ml9Q== X-Gm-Message-State: AOAM530XoH6/VIIk18P3/yvF9EMRE6XffItbPq2m3vU86Ukr5o/DbQ41 W6vU6fP8LoZ3k1FQK4wZ7FR/gW4+CU0= X-Google-Smtp-Source: ABdhPJwC/G7ZNMUH09iCSbBS8+JPCxA0Da4C20euaz9kQmRRIrIGAji2mfv0p4FbcehJHynloffEtg== X-Received: by 2002:a17:906:4b47:: with SMTP id j7mr123992ejv.148.1629148517521; Mon, 16 Aug 2021 14:15:17 -0700 (PDT) Received: from localhost.localdomain ([85.187.18.107]) by smtp.gmail.com with ESMTPSA id j29sm147890ejo.10.2021.08.16.14.15.16 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Aug 2021 14:15:17 -0700 (PDT) From: Vladislav Odintsov To: dev@openvswitch.org Date: Tue, 17 Aug 2021 00:15:06 +0300 Message-Id: <20210816211507.40325-3-odivlad@gmail.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210816211507.40325-1-odivlad@gmail.com> References: <20210816211507.40325-1-odivlad@gmail.com> MIME-Version: 1.0 Cc: Vladislav Odintsov Subject: [ovs-dev] [PATCH ovn 2/3] northd: support for RouteTables in LRs 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: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" This patch extends Logical Router's routing functionality. Now user may create multiple routing tables within a Logical Router and assign them to Logical Router Ports. Traffic coming from Logical Router Port with assigned route_table is checked against global routes if any (Logical_Router_Static_Routes whith empty route_table field), next against directly connected routes and then Logical_Router_Static_Routes with same route_table value as in Logical_Router_Port options:route_table field. A new Logical Router ingress table #10 is added - IN_IP_ROUTING_PRE. In this table packets which come from LRPs with configured options:route_table field are checked against inport and in OVS register 7 unique non-zero value identifying route table is written. Then in 11th table IN_IP_ROUTING routes which have non-empty `route_table` field are added with additional match on reg7 value associated with appropriate route_table. Signed-off-by: Vladislav Odintsov Signed-off-by: Vladislav Odintsov > Signed-off-by: Vladislav Odintsov > --- northd/ovn-northd.8.xml | 63 ++++-- northd/ovn-northd.c | 198 +++++++++++++++--- ovn-nb.ovsschema | 5 +- ovn-nb.xml | 30 +++ tests/ovn-northd.at | 72 ++++++- tests/ovn.at | 438 +++++++++++++++++++++++++++++++++++++++- 6 files changed, 751 insertions(+), 55 deletions(-) diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index 9b69e4e57..2898d9240 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -2868,7 +2868,7 @@ icmp6 {

If ECMP routes with symmetric reply are configured in the - OVN_Northbound database for a gateway router, a priority-300 + OVN_Northbound database for a gateway router, a priority-400 flow is added for each router port on which symmetric replies are configured. The matching logic for these ports essentially reverses the configured logic of the ECMP route. So for instance, a route with a @@ -3213,7 +3213,35 @@ output; -

Ingress Table 10: IP Routing

+

Ingress Table 10: IP Routing Pre

+ +

+ If a packet arrived at this table from Logical Router Port P + which has options:route_table value set, a logical flow with + match inport == "P" with priority 100 and action, + setting unique-generated per-datapath 32-bit value (non-zero) in OVS + register 7. This register is checked in next table. +

+ +

+ This table contains the following logical flows: +

+ +
    +
  • +

    + Priority-100 flow with match inport == "LRP_NAME" value + and action, which set route table identifier in reg7. +

    + +

    + A priority-0 logical flow with match 1 has actions + next;. +

    +
  • +
+ +

Ingress Table 11: IP Routing

A packet that arrives at this table is an IP packet that should be @@ -3284,10 +3312,10 @@ output;

IPv4 routing table. For each route to IPv4 network N with netmask M, on router port P with IP address - A and Ethernet - address E, a logical flow with match ip4.dst == - N/M, whose priority is the number of - 1-bits in M, has the following actions: + A and Ethernet address E, a logical flow with + match ip4.dst == N/M, whose + priority is 100 + the number of 1-bits in M, has the + following actions:

@@ -3350,6 +3378,13 @@ next;
           If the address A is in the link-local scope, the
           route will be limited to sending on the ingress port.
         

+ +

+ For routes with route_table value set + reg7 == id is prefixed in logical flow match portion. + Priority for routes with route_table value set is + the number of 1-bits in M. +

  • @@ -3376,7 +3411,7 @@ select(reg8[16..31], MID1, MID2, ...);
  • -

    Ingress Table 11: IP_ROUTING_ECMP

    +

    Ingress Table 12: IP_ROUTING_ECMP

    This table implements the second part of IP routing for ECMP routes @@ -3428,7 +3463,7 @@ outport = P; -

    Ingress Table 12: Router policies

    +

    Ingress Table 13: Router policies

    This table adds flows for the logical router policies configured on the logical router. Please see the @@ -3500,7 +3535,7 @@ next; -

    Ingress Table 13: ECMP handling for router policies

    +

    Ingress Table 14: ECMP handling for router policies

    This table handles the ECMP for the router policies configured with multiple nexthops. @@ -3544,7 +3579,7 @@ outport = P -

    Ingress Table 14: ARP/ND Resolution

    +

    Ingress Table 15: ARP/ND Resolution

    Any packet that reaches this table is an IP packet whose next-hop @@ -3735,7 +3770,7 @@ outport = P -

    Ingress Table 15: Check packet length

    +

    Ingress Table 16: Check packet length

    For distributed logical routers or gateway routers with gateway @@ -3765,7 +3800,7 @@ REGBIT_PKT_LARGER = check_pkt_larger(L); next; and advances to the next table.

    -

    Ingress Table 16: Handle larger packets

    +

    Ingress Table 17: Handle larger packets

    For distributed logical routers or gateway routers with gateway port @@ -3828,7 +3863,7 @@ icmp6 { and advances to the next table.

    -

    Ingress Table 17: Gateway Redirect

    +

    Ingress Table 18: Gateway Redirect

    For distributed logical routers where one or more of the logical router @@ -3875,7 +3910,7 @@ icmp6 { -

    Ingress Table 18: ARP Request

    +

    Ingress Table 19: ARP Request

    In the common case where the Ethernet destination has been resolved, this diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index e80876af1..f35699bbb 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -197,15 +197,16 @@ enum ovn_stage { PIPELINE_STAGE(ROUTER, IN, ECMP_STATEFUL, 7, "lr_in_ecmp_stateful") \ PIPELINE_STAGE(ROUTER, IN, ND_RA_OPTIONS, 8, "lr_in_nd_ra_options") \ PIPELINE_STAGE(ROUTER, IN, ND_RA_RESPONSE, 9, "lr_in_nd_ra_response") \ - PIPELINE_STAGE(ROUTER, IN, IP_ROUTING, 10, "lr_in_ip_routing") \ - PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_ECMP, 11, "lr_in_ip_routing_ecmp") \ - PIPELINE_STAGE(ROUTER, IN, POLICY, 12, "lr_in_policy") \ - PIPELINE_STAGE(ROUTER, IN, POLICY_ECMP, 13, "lr_in_policy_ecmp") \ - PIPELINE_STAGE(ROUTER, IN, ARP_RESOLVE, 14, "lr_in_arp_resolve") \ - PIPELINE_STAGE(ROUTER, IN, CHK_PKT_LEN , 15, "lr_in_chk_pkt_len") \ - PIPELINE_STAGE(ROUTER, IN, LARGER_PKTS, 16, "lr_in_larger_pkts") \ - PIPELINE_STAGE(ROUTER, IN, GW_REDIRECT, 17, "lr_in_gw_redirect") \ - PIPELINE_STAGE(ROUTER, IN, ARP_REQUEST, 18, "lr_in_arp_request") \ + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_PRE, 10, "lr_in_ip_routing_pre") \ + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING, 11, "lr_in_ip_routing") \ + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_ECMP, 12, "lr_in_ip_routing_ecmp") \ + PIPELINE_STAGE(ROUTER, IN, POLICY, 13, "lr_in_policy") \ + PIPELINE_STAGE(ROUTER, IN, POLICY_ECMP, 14, "lr_in_policy_ecmp") \ + PIPELINE_STAGE(ROUTER, IN, ARP_RESOLVE, 15, "lr_in_arp_resolve") \ + PIPELINE_STAGE(ROUTER, IN, CHK_PKT_LEN, 16, "lr_in_chk_pkt_len") \ + PIPELINE_STAGE(ROUTER, IN, LARGER_PKTS, 17, "lr_in_larger_pkts") \ + PIPELINE_STAGE(ROUTER, IN, GW_REDIRECT, 18, "lr_in_gw_redirect") \ + PIPELINE_STAGE(ROUTER, IN, ARP_REQUEST, 19, "lr_in_arp_request") \ \ /* Logical router egress stages. */ \ PIPELINE_STAGE(ROUTER, OUT, UNDNAT, 0, "lr_out_undnat") \ @@ -273,6 +274,7 @@ enum ovn_stage { #define REG_NEXT_HOP_IPV6 "xxreg0" #define REG_SRC_IPV4 "reg1" #define REG_SRC_IPV6 "xxreg1" +#define REG_ROUTE_TABLE_ID "reg7" /* Register used for setting a label for ACLs in a Logical Switch. */ #define REG_LABEL "reg3" @@ -333,8 +335,9 @@ enum ovn_stage { * | R6 | UNUSED | X | | G | IN_IP_ROUTING)| * | | | R | | 1 | | * +-----+--------------------------+ E | UNUSED | | | - * | R7 | UNUSED | G | | | | - * | | | 3 | | | | + * | R7 | ROUTE_TABLE_ID | G | | | | + * | | (>= IN_IP_ROUTING_PRE && | 3 | | | | + * | | <= IN_IP_ROUTING) | 3 | | | | * +-----+--------------------------+---+-----------------+---+---------------+ * | R8 | ECMP_GROUP_ID | | | * | | ECMP_MEMBER_ID | X | | @@ -8410,11 +8413,110 @@ cleanup: ds_destroy(&actions); } +struct route_table_node { + struct hmap_node hmap_node; /* In route_tables */ + uint32_t id; /* starts from 1 */ + const char *name; +}; + +static uint32_t +get_route_table_hash(const char *route_table_name) +{ + return hash_string(route_table_name, 0); +} + +static struct route_table_node * +route_table_find(struct hmap *route_tables, const char *route_table_name) +{ + struct route_table_node *rtb; + uint32_t hash = get_route_table_hash(route_table_name); + + HMAP_FOR_EACH_WITH_HASH (rtb, hmap_node, hash, route_tables) { + if (!strcmp(rtb->name, route_table_name)) { + return rtb; + } + } + return NULL; +} + +static struct route_table_node * +route_table_add(struct hmap *route_tables, const char *route_table_name) +{ + if (hmap_count(route_tables) == UINT16_MAX) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); + VLOG_WARN_RL(&rl, "too many route tables for Logical Router."); + return NULL; + } + + struct route_table_node *rtb = xzalloc(sizeof *rtb); + uint32_t hash = get_route_table_hash(route_table_name); + hmap_insert(route_tables, &rtb->hmap_node, hash); + + rtb->id = hmap_count(route_tables); + rtb->name = route_table_name; + + return rtb; +} + +static uint32_t +get_route_table_id(struct hmap *route_tables, const char *route_table_name) +{ + struct route_table_node *rtb; + + if (!route_table_name || !strlen(route_table_name)) { + return 0; + } + + rtb = route_table_find(route_tables, route_table_name); + if (!rtb) { + rtb = route_table_add(route_tables, route_table_name); + } + + return rtb->id; +} + +static void +route_tables_destroy(struct hmap *route_tables) +{ + struct route_table_node *rtb, *next; + HMAP_FOR_EACH_SAFE (rtb, next, hmap_node, route_tables) { + hmap_remove(route_tables, &rtb->hmap_node); + free(rtb); + } + hmap_destroy(route_tables); +} + +static void +build_route_table_lflow(struct ovn_datapath *od, struct hmap *lflows, + struct nbrec_logical_router_port *lrp, + struct hmap *route_tables) +{ + struct ds match = DS_EMPTY_INITIALIZER; + struct ds actions = DS_EMPTY_INITIALIZER; + + const char *route_table_name = smap_get(&lrp->options, "route_table"); + uint32_t rtb_id = get_route_table_id(route_tables, route_table_name); + if (!rtb_id) { + return; + } + + ds_put_format(&match, "inport == \"%s\"", lrp->name); + ds_put_format(&actions, "%s = %d; next;", + REG_ROUTE_TABLE_ID, rtb_id); + + ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_ROUTING_PRE, 100, + ds_cstr(&match), ds_cstr(&actions)); + + ds_destroy(&match); + ds_destroy(&actions); +} + struct parsed_route { struct ovs_list list_node; struct in6_addr prefix; unsigned int plen; bool is_src_route; + uint32_t route_table_id; uint32_t hash; const struct nbrec_logical_router_static_route *route; bool ecmp_symmetric_reply; @@ -8439,7 +8541,7 @@ find_static_route_outport(struct ovn_datapath *od, struct hmap *ports, * Otherwise return NULL. */ static struct parsed_route * parsed_routes_add(struct ovn_datapath *od, struct hmap *ports, - struct ovs_list *routes, + struct ovs_list *routes, struct hmap *route_tables, const struct nbrec_logical_router_static_route *route, struct hmap *bfd_connections) { @@ -8520,6 +8622,7 @@ parsed_routes_add(struct ovn_datapath *od, struct hmap *ports, struct parsed_route *pr = xzalloc(sizeof *pr); pr->prefix = prefix; pr->plen = plen; + pr->route_table_id = get_route_table_id(route_tables, route->route_table); pr->is_src_route = (route->policy && !strcmp(route->policy, "src-ip")); pr->hash = route_hash(pr); @@ -8553,6 +8656,7 @@ struct ecmp_groups_node { struct in6_addr prefix; unsigned int plen; bool is_src_route; + uint32_t route_table_id; uint16_t route_count; struct ovs_list route_list; /* Contains ecmp_route_list_node */ }; @@ -8561,7 +8665,7 @@ static void ecmp_groups_add_route(struct ecmp_groups_node *group, const struct parsed_route *route) { - if (group->route_count == UINT16_MAX) { + if (group->route_count == UINT16_MAX) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); VLOG_WARN_RL(&rl, "too many routes in a single ecmp group."); return; @@ -8590,6 +8694,7 @@ ecmp_groups_add(struct hmap *ecmp_groups, eg->prefix = route->prefix; eg->plen = route->plen; eg->is_src_route = route->is_src_route; + eg->route_table_id = route->route_table_id; ovs_list_init(&eg->route_list); ecmp_groups_add_route(eg, route); @@ -8603,7 +8708,8 @@ ecmp_groups_find(struct hmap *ecmp_groups, struct parsed_route *route) HMAP_FOR_EACH_WITH_HASH (eg, hmap_node, route->hash, ecmp_groups) { if (ipv6_addr_equals(&eg->prefix, &route->prefix) && eg->plen == route->plen && - eg->is_src_route == route->is_src_route) { + eg->is_src_route == route->is_src_route && + eg->route_table_id == route->route_table_id) { return eg; } } @@ -8650,7 +8756,8 @@ unique_routes_remove(struct hmap *unique_routes, HMAP_FOR_EACH_WITH_HASH (ur, hmap_node, route->hash, unique_routes) { if (ipv6_addr_equals(&route->prefix, &ur->route->prefix) && route->plen == ur->route->plen && - route->is_src_route == ur->route->is_src_route) { + route->is_src_route == ur->route->is_src_route && + route->route_table_id == ur->route->route_table_id) { hmap_remove(unique_routes, &ur->hmap_node); const struct parsed_route *existed_route = ur->route; free(ur); @@ -8688,9 +8795,9 @@ build_route_prefix_s(const struct in6_addr *prefix, unsigned int plen) } static void -build_route_match(const struct ovn_port *op_inport, const char *network_s, - int plen, bool is_src_route, bool is_ipv4, struct ds *match, - uint16_t *priority) +build_route_match(const struct ovn_port *op_inport, const uint32_t rtb_id, + const char *network_s, int plen, bool is_src_route, + bool is_ipv4, struct ds *match, uint16_t *priority) { const char *dir; /* The priority here is calculated to implement longest-prefix-match @@ -8706,6 +8813,16 @@ build_route_match(const struct ovn_port *op_inport, const char *network_s, if (op_inport) { ds_put_format(match, "inport == %s && ", op_inport->json_key); } + if (rtb_id) { + ds_put_format(match, "%s == %d && ", REG_ROUTE_TABLE_ID, rtb_id); + } + else { + /* Route-table assigned LRPs' routes should have lower priority + * in order not to affect directly-connected global routes. + * So, enlarge non-route-table routes priority by 100. + */ + *priority += 100; + } ds_put_format(match, "ip%s.%s == %s/%d", is_ipv4 ? "4" : "6", dir, network_s, plen); } @@ -8840,7 +8957,7 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows, out_port->lrp_networks.ea_s, IN6_IS_ADDR_V4MAPPED(&route->prefix) ? "" : "xx", port_ip, out_port->json_key); - ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_IP_ROUTING, 300, + ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_IP_ROUTING, 400, ds_cstr(&match), ds_cstr(&actions), &st_route->header_); @@ -8870,8 +8987,8 @@ build_ecmp_route_flow(struct hmap *lflows, struct ovn_datapath *od, struct ds route_match = DS_EMPTY_INITIALIZER; char *prefix_s = build_route_prefix_s(&eg->prefix, eg->plen); - build_route_match(NULL, prefix_s, eg->plen, eg->is_src_route, is_ipv4, - &route_match, &priority); + build_route_match(NULL, eg->route_table_id, prefix_s, eg->plen, + eg->is_src_route, is_ipv4, &route_match, &priority); free(prefix_s); struct ds actions = DS_EMPTY_INITIALIZER; @@ -8946,8 +9063,8 @@ static void add_route(struct hmap *lflows, struct ovn_datapath *od, const struct ovn_port *op, const char *lrp_addr_s, const char *network_s, int plen, const char *gateway, - bool is_src_route, const struct ovsdb_idl_row *stage_hint, - bool is_discard_route) + bool is_src_route, const uint32_t rtb_id, + const struct ovsdb_idl_row *stage_hint, bool is_discard_route) { bool is_ipv4 = strchr(network_s, '.') ? true : false; struct ds match = DS_EMPTY_INITIALIZER; @@ -8962,8 +9079,8 @@ add_route(struct hmap *lflows, struct ovn_datapath *od, op_inport = op; } } - build_route_match(op_inport, network_s, plen, is_src_route, is_ipv4, - &match, &priority); + build_route_match(op_inport, rtb_id, network_s, plen, is_src_route, + is_ipv4, &match, &priority); struct ds common_actions = DS_EMPTY_INITIALIZER; struct ds actions = DS_EMPTY_INITIALIZER; @@ -9026,7 +9143,8 @@ build_static_route_flow(struct hmap *lflows, struct ovn_datapath *od, char *prefix_s = build_route_prefix_s(&route_->prefix, route_->plen); add_route(lflows, route_->is_discard_route ? od : out_port->od, out_port, lrp_addr_s, prefix_s, route_->plen, route->nexthop, - route_->is_src_route, &route->header_, route_->is_discard_route); + route_->is_src_route, route_->route_table_id, &route->header_, + route_->is_discard_route); free(prefix_s); } @@ -10397,6 +10515,17 @@ build_ND_RA_flows_for_lrouter(struct ovn_datapath *od, struct hmap *lflows) } } +/* Logical router ingress table IP_ROUTING_PRE: + * by default goto next. (priority 0). */ +static void +build_ip_routing_pre_flows_for_lrouter(struct ovn_datapath *od, + struct hmap *lflows) +{ + if (od->nbr) { + ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_ROUTING_PRE, 0, "1", "next;"); + } +} + /* Logical router ingress table IP_ROUTING : IP Routing. * * A packet that arrives at this table is an IP packet that should be @@ -10422,14 +10551,14 @@ build_ip_routing_flows_for_lrouter_port( for (int i = 0; i < op->lrp_networks.n_ipv4_addrs; i++) { add_route(lflows, op->od, op, op->lrp_networks.ipv4_addrs[i].addr_s, op->lrp_networks.ipv4_addrs[i].network_s, - op->lrp_networks.ipv4_addrs[i].plen, NULL, false, + op->lrp_networks.ipv4_addrs[i].plen, NULL, false, 0, &op->nbrp->header_, false); } for (int i = 0; i < op->lrp_networks.n_ipv6_addrs; i++) { add_route(lflows, op->od, op, op->lrp_networks.ipv6_addrs[i].addr_s, op->lrp_networks.ipv6_addrs[i].network_s, - op->lrp_networks.ipv6_addrs[i].plen, NULL, false, + op->lrp_networks.ipv6_addrs[i].plen, NULL, false, 0, &op->nbrp->header_, false); } } else if (lsp_is_router(op->nbsp)) { @@ -10452,7 +10581,7 @@ build_ip_routing_flows_for_lrouter_port( add_route(lflows, peer->od, peer, peer->lrp_networks.ipv4_addrs[0].addr_s, laddrs->ipv4_addrs[k].network_s, - laddrs->ipv4_addrs[k].plen, NULL, false, + laddrs->ipv4_addrs[k].plen, NULL, false, 0, &peer->nbrp->header_, false); } } @@ -10472,10 +10601,17 @@ build_static_route_flows_for_lrouter( struct hmap ecmp_groups = HMAP_INITIALIZER(&ecmp_groups); struct hmap unique_routes = HMAP_INITIALIZER(&unique_routes); struct ovs_list parsed_routes = OVS_LIST_INITIALIZER(&parsed_routes); + struct hmap route_tables = HMAP_INITIALIZER(&route_tables); struct ecmp_groups_node *group; + + for (int i = 0; i < od->nbr->n_ports; i++) { + build_route_table_lflow(od, lflows, od->nbr->ports[i], + &route_tables); + } + for (int i = 0; i < od->nbr->n_static_routes; i++) { struct parsed_route *route = - parsed_routes_add(od, ports, &parsed_routes, + parsed_routes_add(od, ports, &parsed_routes, &route_tables, od->nbr->static_routes[i], bfd_connections); if (!route) { continue; @@ -10506,6 +10642,7 @@ build_static_route_flows_for_lrouter( build_static_route_flow(lflows, od, ports, ur->route); } ecmp_groups_destroy(&ecmp_groups); + route_tables_destroy(&route_tables); unique_routes_destroy(&unique_routes); parsed_routes_destroy(&parsed_routes); } @@ -12604,6 +12741,7 @@ build_lswitch_and_lrouter_iterate_by_od(struct ovn_datapath *od, build_neigh_learning_flows_for_lrouter(od, lsi->lflows, &lsi->match, &lsi->actions, lsi->meter_groups); build_ND_RA_flows_for_lrouter(od, lsi->lflows); + build_ip_routing_pre_flows_for_lrouter(od, lsi->lflows); build_static_route_flows_for_lrouter(od, lsi->lflows, lsi->ports, lsi->bfd_connections); build_mcast_lookup_flows_for_lrouter(od, lsi->lflows, &lsi->match, diff --git a/ovn-nb.ovsschema b/ovn-nb.ovsschema index 2ac8ef3ea..a0a171e19 100644 --- a/ovn-nb.ovsschema +++ b/ovn-nb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Northbound", - "version": "5.32.1", - "cksum": "2805328215 29734", + "version": "5.33.1", + "cksum": "3874993350 29785", "tables": { "NB_Global": { "columns": { @@ -387,6 +387,7 @@ "isRoot": false}, "Logical_Router_Static_Route": { "columns": { + "route_table": {"type": "string"}, "ip_prefix": {"type": "string"}, "policy": {"type": {"key": {"type": "string", "enum": ["set", ["src-ip", diff --git a/ovn-nb.xml b/ovn-nb.xml index c56ec62f6..bab80c39c 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -2758,6 +2758,14 @@ prefix according to RFC3663

    + + + Designates lookup Logical_Router_Static_Routes with specified + route_table value. Routes to directly connected networks + from same Logical Router and routes without route_table + option set have higher priority than routes with + route_table option set. + @@ -2877,6 +2885,28 @@

    + +

    + Any string to place route to separate routing table. If Logical Router + Port has configured value in other than empty string, OVN + performs route lookup for all packets entering Logical Router ingress + pipeline from this port in the following manner: +

    + +
      +
    • + 1. First lookup among "global" routes: routes without + route_table value set and routes to directly connected + networks. +
    • +
    • + 2. Next lookup among routes with same route_table value + as specified in LRP's options:route_table field. +
    • +
    +
    + ovn-ic populates this key if the route is learned from the global database. In this case the value diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 5f41112bc..4ee2d18ee 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -5095,7 +5095,7 @@ check ovn-nbctl --wait=sb --ecmp-symmetric-reply lr-route-add lr0 1.0.0.1 192.16 ovn-sbctl dump-flows lr0 > lr0flows AT_CHECK([grep -e "lr_in_ip_routing.*select" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl - table=??(lr_in_ip_routing ), priority=65 , match=(ip4.dst == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; reg8[[16..31]] = select(1, 2);) + table=??(lr_in_ip_routing ), priority=165 , match=(ip4.dst == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; reg8[[16..31]] = select(1, 2);) ]) AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed 's/192\.168\.0\..0/192.168.0.??/' | sed 's/table=../table=??/' | sort], [0], [dnl table=??(lr_in_ip_routing_ecmp), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 1), action=(reg0 = 192.168.0.??; reg1 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; next;) @@ -5108,7 +5108,7 @@ check ovn-nbctl --wait=sb --ecmp-symmetric-reply lr-route-add lr0 1.0.0.1 192.16 ovn-sbctl dump-flows lr0 > lr0flows AT_CHECK([grep -e "lr_in_ip_routing.*select" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl - table=??(lr_in_ip_routing ), priority=65 , match=(ip4.dst == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; reg8[[16..31]] = select(1, 2);) + table=??(lr_in_ip_routing ), priority=165 , match=(ip4.dst == 1.0.0.1/32), action=(ip.ttl--; flags.loopback = 1; reg8[[0..15]] = 1; reg8[[16..31]] = select(1, 2);) ]) AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed 's/192\.168\.0\..0/192.168.0.??/' | sed 's/table=../table=??/' | sort], [0], [dnl table=??(lr_in_ip_routing_ecmp), priority=100 , match=(reg8[[0..15]] == 1 && reg8[[16..31]] == 1), action=(reg0 = 192.168.0.??; reg1 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public"; next;) @@ -5199,3 +5199,71 @@ AT_CHECK([grep lr_in_gw_redirect lrflows | grep cr-DR | sed 's/table=../table=?? AT_CLEANUP ]) + + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([route tables -- flows]) +AT_KEYWORDS([route-tables-flows]) +ovn_start + +check ovn-nbctl lr-add lr0 +check ovn-nbctl lrp-add lr0 lrp0 00:00:00:00:00:01 192.168.0.1/24 +check ovn-nbctl lrp-add lr0 lrp1 00:00:00:00:01:01 192.168.1.1/24 +check ovn-nbctl lrp-add lr0 lrp2 00:00:00:00:02:01 192.168.2.1/24 +check ovn-nbctl lrp-set-options lrp1 route_table=rtb-1 +check ovn-nbctl lrp-set-options lrp2 route_table=rtb-2 + +check ovn-nbctl lr-route-add lr0 0.0.0.0/0 192.168.0.10 +check ovn-nbctl --route-table=rtb-1 lr-route-add lr0 192.168.0.0/24 192.168.1.10 +check ovn-nbctl --route-table=rtb-2 lr-route-add lr0 0.0.0.0/0 192.168.0.10 +check ovn-nbctl --route-table=rtb-2 lr-route-add lr0 1.1.1.1/32 192.168.0.20 +check ovn-nbctl --route-table=rtb-2 lr-route-add lr0 2.2.2.2/32 192.168.0.30 +check ovn-nbctl --route-table=rtb-2 --ecmp lr-route-add lr0 2.2.2.2/32 192.168.0.31 +check ovn-nbctl --wait=sb sync + +ovn-sbctl dump-flows lr0 > lr0flows +AT_CAPTURE_FILE([lr0flows]) + +AT_CHECK([grep -e "lr_in_ip_routing_pre.*match=(1)" lr0flows | sed 's/table=../table=??/'], [0], [dnl + table=??(lr_in_ip_routing_pre), priority=0 , match=(1), action=(next;) +]) + +p1_reg=$(grep -oP "lr_in_ip_routing_pre.*lrp1.*action=\(reg7 = \K." lr0flows) +p2_reg=$(grep -oP "lr_in_ip_routing_pre.*lrp2.*action=\(reg7 = \K." lr0flows) +echo $p1_reg +echo $p2_reg + +# exact register values are not predictable +if [[ $p1_reg -eq 2 ] && [ $p2_reg -eq 1 ]]; then + echo "swap reg values in dump" + sed -i -r s'/^(.*lrp2.*action=\(reg7 = )(1)(.*)/\12\3/g' lr0flows # "reg7 = 1" -> "reg7 = 2" + sed -i -r s'/^(.*lrp1.*action=\(reg7 = )(2)(.*)/\11\3/g' lr0flows # "reg7 = 2" -> "reg7 = 1" + sed -i -r s'/^(.*match=\(reg7 == )(2)( &&.*lrp1.*)/\11\3/g' lr0flows # "reg7 == 2" -> "reg7 == 1" + sed -i -r s'/^(.*match=\(reg7 == )(1)( &&.*lrp0.*)/\12\3/g' lr0flows # "reg7 == 1" -> "reg7 == 2" +fi + +check test $p1_reg != $p2_reg -a $((p1_reg * p2_reg)) -eq 2 + +AT_CHECK([grep "lr_in_ip_routing_pre" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_ip_routing_pre), priority=0 , match=(1), action=(next;) + table=??(lr_in_ip_routing_pre), priority=100 , match=(inport == "lrp1"), action=(reg7 = 1; next;) + table=??(lr_in_ip_routing_pre), priority=100 , match=(inport == "lrp2"), action=(reg7 = 2; next;) +]) + +grep -e "(lr_in_ip_routing ).*outport" lr0flows + +AT_CHECK([grep -e "(lr_in_ip_routing ).*outport" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl + table=??(lr_in_ip_routing ), priority=1 , match=(reg7 == 2 && ip4.dst == 0.0.0.0/0), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.10; reg1 = 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; flags.loopback = 1; next;) + table=??(lr_in_ip_routing ), priority=101 , match=(ip4.dst == 0.0.0.0/0), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.10; reg1 = 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; flags.loopback = 1; next;) + table=??(lr_in_ip_routing ), priority=149 , match=(ip4.dst == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg1 = 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; flags.loopback = 1; next;) + table=??(lr_in_ip_routing ), priority=149 , match=(ip4.dst == 192.168.1.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg1 = 192.168.1.1; eth.src = 00:00:00:00:01:01; outport = "lrp1"; flags.loopback = 1; next;) + table=??(lr_in_ip_routing ), priority=149 , match=(ip4.dst == 192.168.2.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg1 = 192.168.2.1; eth.src = 00:00:00:00:02:01; outport = "lrp2"; flags.loopback = 1; next;) + table=??(lr_in_ip_routing ), priority=229 , match=(inport == "lrp0" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 = fe80::200:ff:fe00:1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; flags.loopback = 1; next;) + table=??(lr_in_ip_routing ), priority=229 , match=(inport == "lrp1" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 = fe80::200:ff:fe00:101; eth.src = 00:00:00:00:01:01; outport = "lrp1"; flags.loopback = 1; next;) + table=??(lr_in_ip_routing ), priority=229 , match=(inport == "lrp2" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 = fe80::200:ff:fe00:201; eth.src = 00:00:00:00:02:01; outport = "lrp2"; flags.loopback = 1; next;) + table=??(lr_in_ip_routing ), priority=49 , match=(reg7 == 1 && ip4.dst == 192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.1.10; reg1 = 192.168.1.1; eth.src = 00:00:00:00:01:01; outport = "lrp1"; flags.loopback = 1; next;) + table=??(lr_in_ip_routing ), priority=65 , match=(reg7 == 2 && ip4.dst == 1.1.1.1/32), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.20; reg1 = 192.168.0.1; eth.src = 00:00:00:00:00:01; outport = "lrp0"; flags.loopback = 1; next;) +]) + +AT_CLEANUP +]) diff --git a/tests/ovn.at b/tests/ovn.at index 8cd4edebe..48092c112 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -17905,7 +17905,7 @@ eth_dst=00000000ff01 ip_src=$(ip_to_hex 10 0 0 10) ip_dst=$(ip_to_hex 172 168 0 101) send_icmp_packet 1 1 $eth_src $eth_dst $ip_src $ip_dst c4c9 0000000000000000000000 -AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | awk '/table=25, n_packets=1, n_bytes=45/{print $7" "$8}'],[0],[dnl +AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | awk '/table=26, n_packets=1, n_bytes=45/{print $7" "$8}'],[0],[dnl priority=80,ip,reg15=0x3,metadata=0x3,nw_src=10.0.0.10 actions=drop ]) @@ -22089,6 +22089,430 @@ OVN_CLEANUP([hv1]) AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([route tables -- global routes]) +ovn_start + +# Logical network: +# ls1 (192.168.1.0/24) - lrp-lr1-ls1 - lr1 - lrp-lr1-ls2 - ls2 (192.168.2.0/24) +# +# ls1 has lsp11 (192.168.1.11) and ls2 has lsp21 (192.168.2.21) and lsp22 +# (192.168.2.22) +# +# lrp-lr1-ls1 set options:route_table=rtb-1 +# +# Static routes on lr1: +# 0.0.0.0/0 nexthop 192.168.2.21 +# 1.1.1.1/32 nexthop 192.168.2.22 route_table=rtb-1 +# +# Test 1: +# lsp11 send packet to 2.2.2.2 +# +# Expected result: +# lsp21 should receive traffic, lsp22 should not receive any traffic +# +# Test 2: +# lsp11 send packet to 1.1.1.1 +# +# Expected result: +# lsp21 should receive traffic, lsp22 should not receive any traffic + +ovn-nbctl lr-add lr1 + +for i in 1 2; do + ovn-nbctl ls-add ls${i} + ovn-nbctl lrp-add lr1 lrp-lr1-ls${i} 00:00:00:01:0${i}:01 192.168.${i}.1/24 + ovn-nbctl lsp-add ls${i} lsp-ls${i}-lr1 -- lsp-set-type lsp-ls${i}-lr1 router \ + -- lsp-set-options lsp-ls${i}-lr1 router-port=lrp-lr1-ls${i} \ + -- lsp-set-addresses lsp-ls${i}-lr1 router +done + +# install static routes +ovn-nbctl lr-route-add lr1 0.0.0.0/0 192.168.2.21 +ovn-nbctl --route-table=rtb-1 lr-route-add lr1 1.1.1.1/32 192.168.2.22 + +# set lrp-lr1-ls1 route table +ovn-nbctl lrp-set-options lrp-lr1-ls1 route_table=rtb-1 + +# Create logical ports +ovn-nbctl lsp-add ls1 lsp11 -- \ + lsp-set-addresses lsp11 "f0:00:00:00:01:11 192.168.1.11" +ovn-nbctl lsp-add ls2 lsp21 -- \ + lsp-set-addresses lsp21 "f0:00:00:00:02:21 192.168.2.21" +ovn-nbctl lsp-add ls2 lsp22 -- \ + lsp-set-addresses lsp22 "f0:00:00:00:02:22 192.168.2.22" + +net_add n1 +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.1 +ovs-vsctl -- add-port br-int hv1-vif1 -- \ + set interface hv1-vif1 external-ids:iface-id=lsp11 \ + options:tx_pcap=hv1/vif1-tx.pcap \ + options:rxq_pcap=hv1/vif1-rx.pcap \ + ofport-request=1 + +ovs-vsctl -- add-port br-int hv1-vif2 -- \ + set interface hv1-vif2 external-ids:iface-id=lsp21 \ + options:tx_pcap=hv1/vif2-tx.pcap \ + options:rxq_pcap=hv1/vif2-rx.pcap \ + ofport-request=2 + +ovs-vsctl -- add-port br-int hv1-vif3 -- \ + set interface hv1-vif3 external-ids:iface-id=lsp22 \ + options:tx_pcap=hv1/vif3-tx.pcap \ + options:rxq_pcap=hv1/vif3-rx.pcap \ + ofport-request=3 + +# wait for earlier changes to take effect +AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore]) + +for i in 1 2; do + packet="inport==\"lsp11\" && eth.src==f0:00:00:00:01:11 && eth.dst==00:00:00:01:01:01 && + ip4 && ip.ttl==64 && ip4.src==192.168.1.11 && ip4.dst==$i.$i.$i.$i && icmp" + AT_CHECK([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) + + # Assume all packets go to lsp21. + exp_packet="eth.src==00:00:00:01:02:01 && eth.dst==f0:00:00:00:02:21 && + ip4 && ip.ttl==63 && ip4.src==192.168.1.11 && ip4.dst==$i.$i.$i.$i && icmp" + echo $exp_packet | ovstest test-ovn expr-to-packets >> expected_lsp21 +done +> expected_lsp22 + +# lsp21 should recieve 2 packets and lsp22 should recieve no packets +OVS_WAIT_UNTIL([ + rcv_n1=`$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > lsp21.packets && cat lsp21.packets | wc -l` + rcv_n2=`$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > lsp22.packets && cat lsp22.packets | wc -l` + echo $rcv_n1 $rcv_n2 + test $rcv_n1 -eq 2 -a $rcv_n2 -eq 0]) + +for i in 1 2; do + sort expected_lsp2$i > expout + AT_CHECK([cat lsp2${i}.packets | sort], [0], [expout]) +done + +OVN_CLEANUP([hv1]) +AT_CLEANUP +]) + + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([route tables -- directly connected routes]) +ovn_start + +# Logical network: +# ls1 (192.168.1.0/24) - lrp-lr1-ls1 - lr1 - lrp-lr1-ls2 - ls2 (192.168.2.0/24) +# +# ls1 has lsp11 (192.168.1.11) and ls2 has lsp21 (192.168.2.21) +# +# lrp-lr1-ls1 set options:route_table=rtb-1 +# +# Static routes on lr1: +# 192.168.2.0/25 nexthop 192.168.1.11 route_table=rtb-1 +# +# Test 1: +# lsp11 send packet to 192.168.2.21 +# +# Expected result: +# lsp21 should receive traffic, lsp11 should not receive any traffic + +ovn-nbctl lr-add lr1 + +for i in 1 2; do + ovn-nbctl ls-add ls${i} + ovn-nbctl lrp-add lr1 lrp-lr1-ls${i} 00:00:00:01:0${i}:01 192.168.${i}.1/24 + ovn-nbctl lsp-add ls${i} lsp-ls${i}-lr1 -- lsp-set-type lsp-ls${i}-lr1 router \ + -- lsp-set-options lsp-ls${i}-lr1 router-port=lrp-lr1-ls${i} \ + -- lsp-set-addresses lsp-ls${i}-lr1 router +done + +# install static route, which overrides directly-connected routes +ovn-nbctl --route-table=rtb-1 lr-route-add lr1 192.168.2.0/25 192.168.1.11 + +# set lrp-lr1-ls1 route table +ovn-nbctl lrp-set-options lrp-lr1-ls1 route_table=rtb-1 + +# Create logical ports +ovn-nbctl lsp-add ls1 lsp11 -- \ + lsp-set-addresses lsp11 "f0:00:00:00:01:11 192.168.1.11" +ovn-nbctl lsp-add ls2 lsp21 -- \ + lsp-set-addresses lsp21 "f0:00:00:00:02:21 192.168.2.21" + +net_add n1 +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.1 +ovs-vsctl -- add-port br-int hv1-vif1 -- \ + set interface hv1-vif1 external-ids:iface-id=lsp11 \ + options:tx_pcap=hv1/vif1-tx.pcap \ + options:rxq_pcap=hv1/vif1-rx.pcap \ + ofport-request=1 + +ovs-vsctl -- add-port br-int hv1-vif2 -- \ + set interface hv1-vif2 external-ids:iface-id=lsp21 \ + options:tx_pcap=hv1/vif2-tx.pcap \ + options:rxq_pcap=hv1/vif2-rx.pcap \ + ofport-request=2 + +# wait for earlier changes to take effect +AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore]) + +packet="inport==\"lsp11\" && eth.src==f0:00:00:00:01:11 && eth.dst==00:00:00:01:01:01 && + ip4 && ip.ttl==64 && ip4.src==192.168.1.11 && ip4.dst==192.168.2.21 && icmp" +AT_CHECK([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) + +# Assume all packets go to lsp21. +exp_packet="eth.src==00:00:00:01:02:01 && eth.dst==f0:00:00:00:02:21 && + ip4 && ip.ttl==63 && ip4.src==192.168.1.11 && ip4.dst==192.168.2.21 && icmp" +echo $exp_packet | ovstest test-ovn expr-to-packets >> expected_lsp21 +> expected_lsp11 + +# lsp21 should recieve 1 icmp packet and lsp11 should recieve no packets +OVS_WAIT_UNTIL([ + rcv_n11=`$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > lsp11.packets && cat lsp11.packets | wc -l` + rcv_n21=`$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > lsp21.packets && cat lsp21.packets | wc -l` + echo $rcv_n11 $rcv_n21 + test $rcv_n11 -eq 0 -a $rcv_n21 -eq 1]) + +for i in 11 21; do + sort expected_lsp$i > expout + AT_CHECK([cat lsp${i}.packets | sort], [0], [expout]) +done + +OVN_CLEANUP([hv1]) +AT_CLEANUP +]) + + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([route tables -- overlapping subnets]) +ovn_start + +# Logical network: +# +# ls1 (192.168.1.0/24) - lrp-lr1-ls1 -\ /- lrp-lr1-ls2 - ls2 (192.168.2.0/24) +# lr1 +# ls3 (192.168.3.0/24) - lrp-lr1-ls3 -/ \- lrp-lr1-ls4 - ls4 (192.168.4.0/24) +# +# ls1 has lsp11 (192.168.1.11) +# ls2 has lsp21 (192.168.2.21) +# ls3 has lsp31 (192.168.3.31) +# ls4 has lsp41 (192.168.4.41) +# +# lrp-lr1-ls1 set options:route_table=rtb-1 +# lrp-lr1-ls2 set options:route_table=rtb-2 +# +# Static routes on lr1: +# 10.0.0.0/24 nexthop 192.168.3.31 route_table=rtb-1 +# 10.0.0.0/24 nexthop 192.168.4.41 route_table=rtb-2 +# +# Test 1: +# lsp11 send packet to 10.0.0.1 +# +# Expected result: +# lsp31 should receive traffic, lsp41 should not receive any traffic +# +# Test 2: +# lsp21 send packet to 10.0.0.1 +# +# Expected result: +# lsp41 should receive traffic, lsp31 should not receive any traffic + +ovn-nbctl lr-add lr1 + +# Create logical topology +for i in $(seq 1 4); do + ovn-nbctl ls-add ls${i} + ovn-nbctl lrp-add lr1 lrp-lr1-ls${i} 00:00:00:01:0${i}:01 192.168.${i}.1/24 + ovn-nbctl lsp-add ls${i} lsp-ls${i}-lr1 -- lsp-set-type lsp-ls${i}-lr1 router \ + -- lsp-set-options lsp-ls${i}-lr1 router-port=lrp-lr1-ls${i} \ + -- lsp-set-addresses lsp-ls${i}-lr1 router + ovn-nbctl lsp-add ls$i lsp${i}1 -- \ + lsp-set-addresses lsp${i}1 "f0:00:00:00:0${i}:1${i} 192.168.${i}.${i}1" +done + +# install static routes +ovn-nbctl --route-table=rtb-1 lr-route-add lr1 10.0.0.0/24 192.168.3.31 +ovn-nbctl --route-table=rtb-2 lr-route-add lr1 10.0.0.0/24 192.168.4.41 + +# set lrp-lr1-ls{1,2} route tables +ovn-nbctl lrp-set-options lrp-lr1-ls1 route_table=rtb-1 +ovn-nbctl lrp-set-options lrp-lr1-ls2 route_table=rtb-2 + +net_add n1 +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.1 + +for i in $(seq 1 4); do + ovs-vsctl -- add-port br-int hv1-vif${i} -- \ + set interface hv1-vif${i} external-ids:iface-id=lsp${i}1 \ + options:tx_pcap=hv1/vif${i}-tx.pcap \ + options:rxq_pcap=hv1/vif${i}-rx.pcap \ + ofport-request=${i} +done + +# wait for earlier changes to take effect +AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore]) + +# lsp31 should recieve packet coming from lsp11 +# lsp41 should recieve packet coming from lsp21 +for i in $(seq 1 2); do + di=$(( i + 2)) # dst index + ri=$(( 5 - i)) # reverse index + packet="inport==\"lsp${i}1\" && eth.src==f0:00:00:00:0${i}:1${i} && + eth.dst==00:00:00:01:0${i}:01 && ip4 && ip.ttl==64 && + ip4.src==192.168.${i}.${i}1 && ip4.dst==10.0.0.1 && icmp" + AT_CHECK([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) + + # Assume all packets go to lsp${di}1. + exp_packet="eth.src==00:00:00:01:0${di}:01 && eth.dst==f0:00:00:00:0${di}:1${di} && + ip4 && ip.ttl==63 && ip4.src==192.168.${i}.${i}1 && ip4.dst==10.0.0.1 && icmp" + echo $exp_packet | ovstest test-ovn expr-to-packets >> expected_lsp${di}1 + > expected_lsp${ri}1 + + OVS_WAIT_UNTIL([ + rcv_n1=`$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif${di}-tx.pcap > lsp${di}1.packets && cat lsp${di}1.packets | wc -l` + rcv_n2=`$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif${ri}-tx.pcap > lsp${ri}1.packets && cat lsp${ri}1.packets | wc -l` + echo $rcv_n1 $rcv_n2 + test $rcv_n1 -eq 1 -a $rcv_n2 -eq 0]) + + for j in "${di}1" "${ri}1"; do + sort expected_lsp${j} > expout + AT_CHECK([cat lsp${j}.packets | sort], [0], [expout]) + done + + # cleanup tx pcap files + for j in "${di}1" "${ri}1"; do + ovs-vsctl -- remove interface hv1-vif${di} options tx_pcap + > hv1/vif${di}-tx.pcap + ovs-vsctl -- set interface hv1-vif${di} external-ids:iface-id=lsp${di}1 \ + options:tx_pcap=hv1/vif${di}-tx.pcap + done +done + +OVN_CLEANUP([hv1]) +AT_CLEANUP +]) + + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([route tables IPv6 -- overlapping subnets]) +ovn_start + +# Logical network: +# +# ls1 (2001:db8:1::/64) - lrp-lr1-ls1 -\ /- lrp-lr1-ls2 - ls2 (2001:db8:2::/64) +# lr1 +# ls3 (2001:db8:3::/64) - lrp-lr1-ls3 -/ \- lrp-lr1-ls4 - ls4 (2001:db8:4::/64) +# +# ls1 has lsp11 (2001:db8:1::11) +# ls2 has lsp21 (2001:db8:2::21) +# ls3 has lsp31 (2001:db8:3::31) +# ls4 has lsp41 (2001:db8:4::41) +# +# lrp-lr1-ls1 set options:route_table=rtb-1 +# lrp-lr1-ls2 set options:route_table=rtb-2 +# +# Static routes on lr1: +# 2001:db8:2000::/64 nexthop 2001:db8:3::31 route_table=rtb-1 +# 2001:db8:2000::/64 nexthop 2001:db8:3::41 route_table=rtb-2 +# +# Test 1: +# lsp11 send packet to 2001:db8:2000::1 +# +# Expected result: +# lsp31 should receive traffic, lsp41 should not receive any traffic +# +# Test 2: +# lsp21 send packet to 2001:db8:2000::1 +# +# Expected result: +# lsp41 should receive traffic, lsp31 should not receive any traffic + +ovn-nbctl lr-add lr1 + +# Create logical topology +for i in $(seq 1 4); do + ovn-nbctl ls-add ls${i} + ovn-nbctl lrp-add lr1 lrp-lr1-ls${i} 00:00:00:01:0${i}:01 2001:db8:${i}::1/64 + ovn-nbctl lsp-add ls${i} lsp-ls${i}-lr1 -- lsp-set-type lsp-ls${i}-lr1 router \ + -- lsp-set-options lsp-ls${i}-lr1 router-port=lrp-lr1-ls${i} \ + -- lsp-set-addresses lsp-ls${i}-lr1 router + ovn-nbctl lsp-add ls$i lsp${i}1 -- \ + lsp-set-addresses lsp${i}1 "f0:00:00:00:0${i}:1${i} 2001:db8:${i}::${i}1" +done + +# install static routes +ovn-nbctl --route-table=rtb-1 lr-route-add lr1 2001:db8:2000::/64 2001:db8:3::31 +ovn-nbctl --route-table=rtb-2 lr-route-add lr1 2001:db8:2000::/64 2001:db8:4::41 + +# set lrp-lr1-ls{1,2} route tables +ovn-nbctl lrp-set-options lrp-lr1-ls1 route_table=rtb-1 +ovn-nbctl lrp-set-options lrp-lr1-ls2 route_table=rtb-2 + +net_add n1 +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.1 + +for i in $(seq 1 4); do + ovs-vsctl -- add-port br-int hv1-vif${i} -- \ + set interface hv1-vif${i} external-ids:iface-id=lsp${i}1 \ + options:tx_pcap=hv1/vif${i}-tx.pcap \ + options:rxq_pcap=hv1/vif${i}-rx.pcap \ + ofport-request=${i} +done + +# wait for earlier changes to take effect +AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore]) + +# lsp31 should recieve packet coming from lsp11 +# lsp41 should recieve packet coming from lsp21 +for i in $(seq 1 2); do + di=$(( i + 2)) # dst index + ri=$(( 5 - i)) # reverse index + packet="inport==\"lsp${i}1\" && eth.src==f0:00:00:00:0${i}:1${i} && + eth.dst==00:00:00:01:0${i}:01 && ip6 && ip.ttl==64 && + ip6.src==2001:db8:${i}::${i}1 && ip6.dst==2001:db8:2000::1 && icmp6" + AT_CHECK([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) + + # Assume all packets go to lsp${di}1. + exp_packet="eth.src==00:00:00:01:0${di}:01 && eth.dst==f0:00:00:00:0${di}:1${di} && ip6 && + ip.ttl==63 && ip6.src==2001:db8:${i}::${i}1 && ip6.dst==2001:db8:2000::1 && icmp6" + echo $exp_packet | ovstest test-ovn expr-to-packets >> expected_lsp${di}1 + > expected_lsp${ri}1 + + OVS_WAIT_UNTIL([ + rcv_n1=`$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif${di}-tx.pcap > lsp${di}1.packets && cat lsp${di}1.packets | wc -l` + rcv_n2=`$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif${ri}-tx.pcap > lsp${ri}1.packets && cat lsp${ri}1.packets | wc -l` + echo $rcv_n1 $rcv_n2 + test $rcv_n1 -eq 1 -a $rcv_n2 -eq 0]) + + for j in "${di}1" "${ri}1"; do + sort expected_lsp${j} > expout + AT_CHECK([cat lsp${j}.packets | sort], [0], [expout]) + done + + # cleanup tx pcap files + for j in "${di}1" "${ri}1"; do + ovs-vsctl -- remove interface hv1-vif${di} options tx_pcap + > hv1/vif${di}-tx.pcap + ovs-vsctl -- set interface hv1-vif${di} external-ids:iface-id=lsp${di}1 \ + options:tx_pcap=hv1/vif${di}-tx.pcap + done +done + +OVN_CLEANUP([hv1]) +AT_CLEANUP +]) + + OVN_FOR_EACH_NORTHD([ AT_SETUP([forwarding group: 3 HVs, 1 LR, 2 LS]) AT_KEYWORDS([forwarding-group]) @@ -22844,7 +23268,7 @@ ovn-sbctl dump-flows > sbflows AT_CAPTURE_FILE([sbflows]) AT_CAPTURE_FILE([offlows]) OVS_WAIT_UNTIL([ - as hv1 ovs-ofctl dump-flows br-int table=20 > offlows + as hv1 ovs-ofctl dump-flows br-int table=21 > offlows test $(grep -c "load:0x64->NXM_NX_PKT_MARK" offlows) = 1 && \ test $(grep -c "load:0x3->NXM_NX_PKT_MARK" offlows) = 1 && \ test $(grep -c "load:0x4->NXM_NX_PKT_MARK" offlows) = 1 && \ @@ -22937,12 +23361,12 @@ send_ipv4_pkt hv1 hv1-vif1 505400000003 00000000ff01 \ $(ip_to_hex 10 0 0 3) $(ip_to_hex 172 168 0 120) OVS_WAIT_UNTIL([ - test 1 -eq $(as hv1 ovs-ofctl dump-flows br-int table=20 | \ + test 1 -eq $(as hv1 ovs-ofctl dump-flows br-int table=21 | \ grep "load:0x2->NXM_NX_PKT_MARK" -c) ]) AT_CHECK([ - test 0 -eq $(as hv1 ovs-ofctl dump-flows br-int table=20 | \ + test 0 -eq $(as hv1 ovs-ofctl dump-flows br-int table=21 | \ grep "load:0x64->NXM_NX_PKT_MARK" -c) ]) @@ -23645,7 +24069,7 @@ AT_CHECK([ grep "priority=100" | \ grep -c "ct(commit,zone=NXM_NX_REG11\\[[0..15\\]],.*exec(move:NXM_OF_ETH_SRC\\[[\\]]->NXM_NX_CT_LABEL\\[[32..79\\]],load:0x[[0-9]]->NXM_NX_CT_LABEL\\[[80..95\\]]))" - grep table=22 hv${hv}flows | \ + grep table=23 hv${hv}flows | \ grep "priority=200" | \ grep -c "actions=move:NXM_NX_CT_LABEL\\[[32..79\\]]->NXM_OF_ETH_DST\\[[\\]]" done; :], [0], [dnl @@ -23770,7 +24194,7 @@ AT_CHECK([ grep "priority=100" | \ grep -c "ct(commit,zone=NXM_NX_REG11\\[[0..15\\]],.*exec(move:NXM_OF_ETH_SRC\\[[\\]]->NXM_NX_CT_LABEL\\[[32..79\\]],load:0x[[0-9]]->NXM_NX_CT_LABEL\\[[80..95\\]]))" - grep table=22 hv${hv}flows | \ + grep table=23 hv${hv}flows | \ grep "priority=200" | \ grep -c "actions=move:NXM_NX_CT_LABEL\\[[32..79\\]]->NXM_OF_ETH_DST\\[[\\]]" done; :], [0], [dnl @@ -24392,7 +24816,7 @@ AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep "actions=controller" | grep ]) # The packet should've been dropped in the lr_in_arp_resolve stage. -AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep -E "table=22, n_packets=1,.* priority=1,ip,metadata=0x${sw_key},nw_dst=10.0.1.1 actions=drop" -c], [0], [dnl +AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep -E "table=23, n_packets=1,.* priority=1,ip,metadata=0x${sw_key},nw_dst=10.0.1.1 actions=drop" -c], [0], [dnl 1 ]) From patchwork Mon Aug 16 21:15:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladislav Odintsov X-Patchwork-Id: 1517344 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=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) 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=Ecu2xpAe; dkim-atps=neutral Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GpRld5BRzz9sRK for ; Tue, 17 Aug 2021 07:15:41 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id D88EE607D1; Mon, 16 Aug 2021 21:15:37 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id juSawiLLoym8; Mon, 16 Aug 2021 21:15:33 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTPS id 30292607C5; Mon, 16 Aug 2021 21:15:28 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id DE06CC0025; Mon, 16 Aug 2021 21:15:26 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id C2F1DC001D for ; Mon, 16 Aug 2021 21:15:25 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 9C89140336 for ; Mon, 16 Aug 2021 21:15:25 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp2.osuosl.org (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KWFzhoHhf6Qk for ; Mon, 16 Aug 2021 21:15:21 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.8.0 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by smtp2.osuosl.org (Postfix) with ESMTPS id 3FB9D402D2 for ; Mon, 16 Aug 2021 21:15:21 +0000 (UTC) Received: by mail-ed1-x52e.google.com with SMTP id cn28so16613282edb.6 for ; Mon, 16 Aug 2021 14:15:21 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=co7AzOe84eD8JjfaaM+0f20BbaSBoi183oGFL8ebTlU=; b=Ecu2xpAebJVp+6inhitKY170Qa674ygfZSoGIU981Yjn4icvzNGptaPQvKgxS00jw2 whfePhn/CCyadWBAb+spNOokOjTB82AfXln1zMOfvJ4SkkRcDJrNwU69YJCg2XXl+Z78 HMnQqke31qYlbraBDvNrjX9b57dm6RI74LacVy0OlHS/FvVYv0OyjwPaISD4riUTCH/V 6rkH9NoR4LyF195P0yFKX0znVO4a4FJobqYtXcGEOJc3SOqOpERhDO8l9tTjD+bEHTtt d/SW+58DoaedyNahPdBHEwddI8OK1d1MqKSGnYDl2KRtw1yot26v5VVuH6eNFizdybMw T+2A== 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:mime-version:content-transfer-encoding; bh=co7AzOe84eD8JjfaaM+0f20BbaSBoi183oGFL8ebTlU=; b=M0c46BECFb2dBQ4/rTWCkWcEPy8Axnn6rAIaLE9rL33+t4vM7z5fxb8yhrss6xtRyH Ao4P/VwkVzlQ1YdUkm44IgSSolP3BaHmIQa/Pyfk9h0BMneNHCeTQew4iWOv083eBLvB oIFBfKox+15Bj5OJ4ruBlsYDytg3YVYk+vX/DYa8sMZLESRNXJ4dhc0D0G3yHq7TF4WZ czNixYSe2alhdM/5mZu2C5Vp8KLn++uCWe6yniolNSmF6HFcsrWqI91nsa7IyV9BAIz+ mC5yuZ0tc8MSXUwmaEU04q5IoBRoPcLrUkVeFXOvbDAL/X1c1vp7FNSSh5uoPtHZmJ51 eUvw== X-Gm-Message-State: AOAM532apfZGWZ2vTfVi6GEL/cvuOkfuA6VGL5GuQdjHPcZce9HH3jtO rfRDM+M8FSEdvuSi+PQi7sHILMvcyas= X-Google-Smtp-Source: ABdhPJxi9EUyalrxKSrnaO1h/JzhTo0eexLMOwt2tS8g5AHX7nt9xwZPtmVmFYMtv/JJB9ga9Rn1pQ== X-Received: by 2002:aa7:dcd1:: with SMTP id w17mr161410edu.322.1629148519091; Mon, 16 Aug 2021 14:15:19 -0700 (PDT) Received: from localhost.localdomain ([85.187.18.107]) by smtp.gmail.com with ESMTPSA id j29sm147890ejo.10.2021.08.16.14.15.18 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Aug 2021 14:15:18 -0700 (PDT) From: Vladislav Odintsov To: dev@openvswitch.org Date: Tue, 17 Aug 2021 00:15:07 +0300 Message-Id: <20210816211507.40325-4-odivlad@gmail.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210816211507.40325-1-odivlad@gmail.com> References: <20210816211507.40325-1-odivlad@gmail.com> MIME-Version: 1.0 Cc: Vladislav Odintsov Subject: [ovs-dev] [PATCH ovn 3/3] utilities: update ovn-nbctl with RouteTables support 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: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Vladislav Odintsov --- tests/ovn-ic.at | 4 + tests/ovn-nbctl.at | 165 +++++++++++++++++++++++++++++++++++++++++- utilities/ovn-nbctl.c | 124 +++++++++++++++++++++++++++++-- 3 files changed, 284 insertions(+), 9 deletions(-) diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at index 2a4fba031..1f06dedd0 100644 --- a/tests/ovn-ic.at +++ b/tests/ovn-ic.at @@ -229,6 +229,7 @@ done AT_CHECK([ovn_as az1 ovn-nbctl lr-route-list lr1], [0], [dnl IPv4 Routes +Route Table global: 10.11.1.0/24 169.254.0.1 dst-ip 10.11.2.0/24 169.254.100.2 dst-ip (learned) 10.22.1.0/24 169.254.0.2 src-ip @@ -247,6 +248,7 @@ ovn_as az1 ovn-nbctl set nb_global . options:ic-route-learn=false OVS_WAIT_WHILE([ovn_as az1 ovn-nbctl lr-route-list lr1 | grep learned]) AT_CHECK([ovn_as az1 ovn-nbctl lr-route-list lr1], [0], [dnl IPv4 Routes +Route Table global: 10.11.1.0/24 169.254.0.1 dst-ip 10.22.1.0/24 169.254.0.2 src-ip ]) @@ -262,6 +264,7 @@ ovn_as az1 ovn-nbctl set nb_global . options:ic-route-adv=false OVS_WAIT_WHILE([ovn_as az2 ovn-nbctl lr-route-list lr2 | grep learned]) AT_CHECK([ovn_as az2 ovn-nbctl lr-route-list lr2], [0], [dnl IPv4 Routes +Route Table global: 10.11.2.0/24 169.254.0.1 dst-ip 10.22.2.0/24 169.254.0.2 src-ip ]) @@ -280,6 +283,7 @@ done # Default route should NOT get advertised or learned, by default. AT_CHECK([ovn_as az2 ovn-nbctl lr-route-list lr2], [0], [dnl IPv4 Routes +Route Table global: 10.11.1.0/24 169.254.100.1 dst-ip (learned) 10.11.2.0/24 169.254.0.1 dst-ip 10.22.2.0/24 169.254.0.2 src-ip diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at index 4445ab7c0..7f9b4d00a 100644 --- a/tests/ovn-nbctl.at +++ b/tests/ovn-nbctl.at @@ -1515,6 +1515,7 @@ AT_CHECK([ovn-nbctl --ecmp --policy=src-ip lr-route-add lr0 20.0.0.0/24 11.0.0.1 AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv4 Routes +Route Table global: 10.0.0.0/24 11.0.0.1 dst-ip 10.0.1.0/24 11.0.1.1 dst-ip lp0 20.0.0.0/24 discard dst-ip @@ -1527,6 +1528,7 @@ IPv4 Routes AT_CHECK([ovn-nbctl --may-exist lr-route-add lr0 10.0.0.111/24 11.0.0.1 lp1]) AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv4 Routes +Route Table global: 10.0.0.0/24 11.0.0.1 dst-ip lp1 10.0.1.0/24 11.0.1.1 dst-ip lp0 20.0.0.0/24 discard dst-ip @@ -1556,6 +1558,7 @@ AT_CHECK([ovn-nbctl --policy=src-ip lr-route-del lr0 9.16.1.0/24]) AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv4 Routes +Route Table global: 10.0.0.0/24 11.0.0.1 dst-ip lp1 10.0.0.0/24 11.0.0.2 src-ip 0.0.0.0/0 192.168.0.1 dst-ip @@ -1566,6 +1569,7 @@ AT_CHECK([ovn-nbctl --policy=dst-ip lr-route-del lr0 10.0.0.0/24]) AT_CHECK([ovn-nbctl --policy=src-ip lr-route-del lr0 10.0.0.0/24]) AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv4 Routes +Route Table global: 0.0.0.0/0 192.168.0.1 dst-ip ]) @@ -1575,6 +1579,7 @@ AT_CHECK([ovn-nbctl --policy=src-ip lr-route-add lr0 10.0.0.0/24 11.0.0.2]) AT_CHECK([ovn-nbctl lr-route-del lr0 10.0.0.0/24]) AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv4 Routes +Route Table global: 0.0.0.0/0 192.168.0.1 dst-ip ]) @@ -1590,6 +1595,7 @@ AT_CHECK([ovn-nbctl --ecmp lr-route-add lr0 10.0.0.0/24 11.0.0.3]) AT_CHECK([ovn-nbctl --ecmp lr-route-add lr0 10.0.0.0/24 11.0.0.4 lp0]) AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv4 Routes +Route Table global: 10.0.0.0/24 11.0.0.1 dst-ip ecmp 10.0.0.0/24 11.0.0.2 dst-ip ecmp 10.0.0.0/24 11.0.0.3 dst-ip ecmp @@ -1604,6 +1610,7 @@ dnl Delete ecmp routes AT_CHECK([ovn-nbctl lr-route-del lr0 10.0.0.0/24 11.0.0.1]) AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv4 Routes +Route Table global: 10.0.0.0/24 11.0.0.2 dst-ip ecmp 10.0.0.0/24 11.0.0.3 dst-ip ecmp 10.0.0.0/24 11.0.0.4 dst-ip lp0 ecmp @@ -1611,12 +1618,14 @@ IPv4 Routes AT_CHECK([ovn-nbctl lr-route-del lr0 10.0.0.0/24 11.0.0.2]) AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv4 Routes +Route Table global: 10.0.0.0/24 11.0.0.3 dst-ip ecmp 10.0.0.0/24 11.0.0.4 dst-ip lp0 ecmp ]) AT_CHECK([ovn-nbctl lr-route-del lr0 10.0.0.0/24 11.0.0.4 lp0]) AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv4 Routes +Route Table global: 10.0.0.0/24 11.0.0.3 dst-ip ]) AT_CHECK([ovn-nbctl lr-route-del lr0 10.0.0.0/24 11.0.0.3]) @@ -1630,6 +1639,7 @@ AT_CHECK([ovn-nbctl lr-route-add lr0 2001:0db8:1::/64 2001:0db8:0:f103::1]) AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv6 Routes +Route Table global: 2001:db8::/64 2001:db8:0:f102::1 dst-ip lp0 2001:db8:1::/64 2001:db8:0:f103::1 dst-ip ::/0 2001:db8:0:f101::1 dst-ip @@ -1639,6 +1649,7 @@ AT_CHECK([ovn-nbctl lr-route-del lr0 2001:0db8:0::/64]) AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv6 Routes +Route Table global: 2001:db8:1::/64 2001:db8:0:f103::1 dst-ip ::/0 2001:db8:0:f101::1 dst-ip ]) @@ -1666,11 +1677,13 @@ AT_CHECK([ovn-nbctl --may-exist --ecmp-symmetric-reply lr-route-add lr0 2003:0db AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl IPv4 Routes +Route Table global: 10.0.0.0/24 11.0.0.1 dst-ip 10.0.1.0/24 11.0.1.1 dst-ip lp0 0.0.0.0/0 192.168.0.1 dst-ip IPv6 Routes +Route Table global: 2001:db8::/64 2001:db8:0:f102::1 dst-ip lp0 2001:db8:1::/64 2001:db8:0:f103::1 dst-ip ecmp 2001:db8:1::/64 2001:db8:0:f103::2 dst-ip ecmp @@ -1685,7 +1698,157 @@ AT_CHECK([ovn-nbctl lrp-add lr0 lr0-p0 00:00:01:01:02:03 192.168.10.1/24]) bfd_uuid=$(ovn-nbctl create bfd logical_port=lr0-p0 dst_ip=100.0.0.50 status=down min_tx=250 min_rx=250 detect_mult=10) AT_CHECK([ovn-nbctl lr-route-add lr0 100.0.0.0/24 192.168.0.1]) route_uuid=$(fetch_column nb:logical_router_static_route _uuid ip_prefix="100.0.0.0/24") -AT_CHECK([ovn-nbctl set logical_router_static_route $route_uuid bfd=$bfd_uuid])]) +AT_CHECK([ovn-nbctl set logical_router_static_route $route_uuid bfd=$bfd_uuid]) + +check ovn-nbctl lr-route-del lr0 +AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl +]) + +dnl Check IPv4 routes in route table +check ovn-nbctl --route-table=rtb-1 lr-route-add lr0 0.0.0.0/0 192.168.0.1 +check ovn-nbctl --route-table=rtb-1 lr-route-add lr0 10.0.1.1/24 11.0.1.1 lp0 +check ovn-nbctl --route-table=rtb-1 lr-route-add lr0 10.0.0.1/24 11.0.0.1 +AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl +IPv4 Routes +Route Table rtb-1: + 10.0.0.0/24 11.0.0.1 dst-ip + 10.0.1.0/24 11.0.1.1 dst-ip lp0 + 0.0.0.0/0 192.168.0.1 dst-ip +]) + +check ovn-nbctl lr-route-del lr0 +AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl +]) + +dnl Check IPv6 routes in route table +check ovn-nbctl --route-table=rtb-1 lr-route-add lr0 0:0:0:0:0:0:0:0/0 2001:0db8:0:f101::1 +check ovn-nbctl --route-table=rtb-1 lr-route-add lr0 2001:0db8:0::/64 2001:0db8:0:f102::1 lp0 +check ovn-nbctl --route-table=rtb-1 lr-route-add lr0 2001:0db8:1::/64 2001:0db8:0:f103::1 + +AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl +IPv6 Routes +Route Table rtb-1: + 2001:db8::/64 2001:db8:0:f102::1 dst-ip lp0 + 2001:db8:1::/64 2001:db8:0:f103::1 dst-ip + ::/0 2001:db8:0:f101::1 dst-ip +]) + +dnl Check IPv4 and IPv6 routes in route table +check ovn-nbctl --route-table=rtb-1 lr-route-add lr0 0.0.0.0/0 192.168.0.1 +check ovn-nbctl --route-table=rtb-1 lr-route-add lr0 10.0.1.1/24 11.0.1.1 lp0 +check ovn-nbctl --route-table=rtb-1 lr-route-add lr0 10.0.0.1/24 11.0.0.1 + +AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl +IPv4 Routes +Route Table rtb-1: + 10.0.0.0/24 11.0.0.1 dst-ip + 10.0.1.0/24 11.0.1.1 dst-ip lp0 + 0.0.0.0/0 192.168.0.1 dst-ip + +IPv6 Routes +Route Table rtb-1: + 2001:db8::/64 2001:db8:0:f102::1 dst-ip lp0 + 2001:db8:1::/64 2001:db8:0:f103::1 dst-ip + ::/0 2001:db8:0:f101::1 dst-ip +]) + +# Add routes in another route table +check ovn-nbctl --route-table=rtb-2 lr-route-add lr0 0.0.0.0/0 192.168.0.1 +check ovn-nbctl --route-table=rtb-2 lr-route-add lr0 10.0.1.1/24 11.0.1.1 lp0 +check ovn-nbctl --route-table=rtb-2 lr-route-add lr0 10.0.0.1/24 11.0.0.1 +check ovn-nbctl --route-table=rtb-2 lr-route-add lr0 0:0:0:0:0:0:0:0/0 2001:0db8:0:f101::1 +check ovn-nbctl --route-table=rtb-2 lr-route-add lr0 2001:0db8:0::/64 2001:0db8:0:f102::1 lp0 +check ovn-nbctl --route-table=rtb-2 lr-route-add lr0 2001:0db8:1::/64 2001:0db8:0:f103::1 + +AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl +IPv4 Routes +Route Table rtb-1: + 10.0.0.0/24 11.0.0.1 dst-ip + 10.0.1.0/24 11.0.1.1 dst-ip lp0 + 0.0.0.0/0 192.168.0.1 dst-ip + +Route Table rtb-2: + 10.0.0.0/24 11.0.0.1 dst-ip + 10.0.1.0/24 11.0.1.1 dst-ip lp0 + 0.0.0.0/0 192.168.0.1 dst-ip + +IPv6 Routes +Route Table rtb-1: + 2001:db8::/64 2001:db8:0:f102::1 dst-ip lp0 + 2001:db8:1::/64 2001:db8:0:f103::1 dst-ip + ::/0 2001:db8:0:f101::1 dst-ip + +Route Table rtb-2: + 2001:db8::/64 2001:db8:0:f102::1 dst-ip lp0 + 2001:db8:1::/64 2001:db8:0:f103::1 dst-ip + ::/0 2001:db8:0:f101::1 dst-ip +]) + +# Add routes to global route table +check ovn-nbctl lr-route-add lr0 0.0.0.0/0 192.168.0.1 +check ovn-nbctl lr-route-add lr0 10.0.1.1/24 11.0.1.1 lp0 +check ovn-nbctl lr-route-add lr0 10.0.0.1/24 11.0.0.1 +check ovn-nbctl lr-route-add lr0 0:0:0:0:0:0:0:0/0 2001:0db8:0:f101::1 +check ovn-nbctl lr-route-add lr0 2001:0db8:0::/64 2001:0db8:0:f102::1 lp0 +check check ovn-nbctl lr-route-add lr0 2001:0db8:1::/64 2001:0db8:0:f103::1 + +AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl +IPv4 Routes +Route Table global: + 10.0.0.0/24 11.0.0.1 dst-ip + 10.0.1.0/24 11.0.1.1 dst-ip lp0 + 0.0.0.0/0 192.168.0.1 dst-ip + +Route Table rtb-1: + 10.0.0.0/24 11.0.0.1 dst-ip + 10.0.1.0/24 11.0.1.1 dst-ip lp0 + 0.0.0.0/0 192.168.0.1 dst-ip + +Route Table rtb-2: + 10.0.0.0/24 11.0.0.1 dst-ip + 10.0.1.0/24 11.0.1.1 dst-ip lp0 + 0.0.0.0/0 192.168.0.1 dst-ip + +IPv6 Routes +Route Table global: + 2001:db8::/64 2001:db8:0:f102::1 dst-ip lp0 + 2001:db8:1::/64 2001:db8:0:f103::1 dst-ip + ::/0 2001:db8:0:f101::1 dst-ip + +Route Table rtb-1: + 2001:db8::/64 2001:db8:0:f102::1 dst-ip lp0 + 2001:db8:1::/64 2001:db8:0:f103::1 dst-ip + ::/0 2001:db8:0:f101::1 dst-ip + +Route Table rtb-2: + 2001:db8::/64 2001:db8:0:f102::1 dst-ip lp0 + 2001:db8:1::/64 2001:db8:0:f103::1 dst-ip + ::/0 2001:db8:0:f101::1 dst-ip +]) +check ovn-nbctl lr-route-del lr0 + +# ECMP route in route table +check ovn-nbctl --route-table=rtb1 lr-route-add lr0 0.0.0.0/0 192.168.0.1 +check ovn-nbctl --ecmp --route-table=rtb1 lr-route-add lr0 0.0.0.0/0 192.168.0.2 + +# Negative route table case: same prefix +AT_CHECK([ovn-nbctl --route-table=rtb1 lr-route-add lr0 0.0.0.0/0 192.168.0.1], [1], [], [dnl +ovn-nbctl: duplicate prefix: 0.0.0.0/0 (policy: dst-ip). Use option --ecmp to allow this for ECMP routing. +]) + +# Negative route table case: same prefix & nexthop with ecmp +AT_CHECK([ovn-nbctl --ecmp --route-table=rtb1 lr-route-add lr0 0.0.0.0/0 192.168.0.2], [1], [], [dnl +ovn-nbctl: duplicate nexthop for the same ECMP route +]) + +# Add routes to global route table +check ovn-nbctl lrp-add lr0 lrp0 00:00:00:00:00:01 1.1.1.1/24 +check ovn-nbctl lrp-set-options lrp0 route_table=rtb1 +AT_CHECK([ovn-nbctl get logical-router-port lrp0 options:route_table], [0], [dnl +rtb1 +]) +check `ovn-nbctl show lr0 | grep lrp0 -A3 | grep route_table=rtb1` +]) dnl --------------------------------------------------------------------- diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c index ada53b662..4e919ddfe 100644 --- a/utilities/ovn-nbctl.c +++ b/utilities/ovn-nbctl.c @@ -329,6 +329,8 @@ Logical router port commands:\n\ add logical port PORT on ROUTER\n\ lrp-set-gateway-chassis PORT CHASSIS [PRIORITY]\n\ set gateway chassis for port PORT\n\ + lrp-set-options PORT KEY=VALUE [KEY=VALUE]...\n\ + set router port options\n\ lrp-del-gateway-chassis PORT CHASSIS\n\ delete gateway chassis from port PORT\n\ lrp-get-gateway-chassis PORT\n\ @@ -351,10 +353,15 @@ Logical router port commands:\n\ ('overlay' or 'bridged')\n\ \n\ Route commands:\n\ - [--policy=POLICY] [--ecmp] [--ecmp-symmetric-reply] lr-route-add ROUTER \n\ - PREFIX NEXTHOP [PORT]\n\ + [--policy=POLICY]\n\ + [--ecmp]\n\ + [--ecmp-symmetric-reply]\n\ + [--route-table=ROUTE_TABLE]\n\ + lr-route-add ROUTER PREFIX NEXTHOP [PORT]\n\ add a route to ROUTER\n\ - [--policy=POLICY] lr-route-del ROUTER [PREFIX [NEXTHOP [PORT]]]\n\ + [--policy=POLICY]\n\ + [--route-table=ROUTE_TABLE]\n\ + lr-route-del ROUTER [PREFIX [NEXTHOP [PORT]]]\n\ remove routes from ROUTER\n\ lr-route-list ROUTER print routes for ROUTER\n\ \n\ @@ -743,6 +750,11 @@ print_lr(const struct nbrec_logical_router *lr, struct ds *s) ds_put_cstr(s, "]\n"); } + const char *route_table = smap_get(&lrp->options, "route_table"); + if (route_table) { + ds_put_format(s, " route-table: %s\n", route_table); + } + if (lrp->n_gateway_chassis) { const struct nbrec_gateway_chassis **gcs; @@ -860,6 +872,7 @@ nbctl_pre_show(struct ctl_context *ctx) ovsdb_idl_add_column(ctx->idl, &nbrec_logical_router_port_col_name); ovsdb_idl_add_column(ctx->idl, &nbrec_logical_router_port_col_mac); ovsdb_idl_add_column(ctx->idl, &nbrec_logical_router_port_col_networks); + ovsdb_idl_add_column(ctx->idl, &nbrec_logical_router_port_col_options); ovsdb_idl_add_column(ctx->idl, &nbrec_logical_router_port_col_gateway_chassis); ovsdb_idl_add_column(ctx->idl, &nbrec_gateway_chassis_col_chassis_name); @@ -3998,11 +4011,19 @@ nbctl_lr_policy_list(struct ctl_context *ctx) static struct nbrec_logical_router_static_route * nbctl_lr_get_route(const struct nbrec_logical_router *lr, char *prefix, - char *next_hop, bool is_src_route, bool ecmp) + char *next_hop, bool is_src_route, bool ecmp, + char *route_table) { for (int i = 0; i < lr->n_static_routes; i++) { struct nbrec_logical_router_static_route *route = lr->static_routes[i]; + /* Strict compare for route_table. + * If route_table was not specified, + * lookup for routes with empty route_table value. */ + if (strcmp(route->route_table, route_table ? route_table : "")) { + continue; + } + /* Compare route policy. */ char *nb_policy = route->policy; bool nb_is_src_route = false; @@ -4056,6 +4077,8 @@ nbctl_pre_lr_route_add(struct ctl_context *ctx) &nbrec_logical_router_static_route_col_bfd); ovsdb_idl_add_column(ctx->idl, &nbrec_logical_router_static_route_col_options); + ovsdb_idl_add_column(ctx->idl, + &nbrec_logical_router_static_route_col_route_table); } static void @@ -4081,6 +4104,7 @@ nbctl_lr_route_add(struct ctl_context *ctx) } } + char *route_table = shash_find_data(&ctx->options, "--route-table"); bool v6_prefix = false; prefix = normalize_ipv4_prefix_str(ctx->argv[2]); if (!prefix) { @@ -4135,7 +4159,8 @@ nbctl_lr_route_add(struct ctl_context *ctx) bool ecmp = shash_find(&ctx->options, "--ecmp") != NULL || ecmp_symmetric_reply; struct nbrec_logical_router_static_route *route = - nbctl_lr_get_route(lr, prefix, next_hop, is_src_route, ecmp); + nbctl_lr_get_route(lr, prefix, next_hop, is_src_route, ecmp, + route_table); /* Validations for nexthop = "discard" */ if (is_discard_route) { @@ -4199,7 +4224,8 @@ nbctl_lr_route_add(struct ctl_context *ctx) } struct nbrec_logical_router_static_route *discard_route = - nbctl_lr_get_route(lr, prefix, "discard", is_src_route, true); + nbctl_lr_get_route(lr, prefix, "discard", is_src_route, true, + route_table); if (discard_route) { ctl_error(ctx, "discard nexthop for the same ECMP route exists."); goto cleanup; @@ -4214,6 +4240,9 @@ nbctl_lr_route_add(struct ctl_context *ctx) if (policy) { nbrec_logical_router_static_route_set_policy(route, policy); } + if (route_table) { + nbrec_logical_router_static_route_set_route_table(route, route_table); + } if (ecmp_symmetric_reply) { const struct smap options = SMAP_CONST1(&options, @@ -4268,6 +4297,7 @@ nbctl_lr_route_del(struct ctl_context *ctx) return; } + const char *route_table = shash_find_data(&ctx->options, "--route-table"); const char *policy = shash_find_data(&ctx->options, "--policy"); bool is_src_route = false; if (policy) { @@ -4358,6 +4388,14 @@ nbctl_lr_route_del(struct ctl_context *ctx) } } + /* Strict compare for route_table. + * If route_table was not specified, + * lookup for routes with empty route_table value. */ + if (strcmp(lr->static_routes[i]->route_table, + route_table ? route_table : "")) { + continue; + } + /* Compare output_port, if specified. */ if (output_port) { char *rt_output_port = lr->static_routes[i]->output_port; @@ -5081,6 +5119,41 @@ nbctl_pre_lrp_del_gateway_chassis(struct ctl_context *ctx) ovsdb_idl_add_column(ctx->idl, &nbrec_gateway_chassis_col_chassis_name); } +static void +nbctl_pre_lrp_options(struct ctl_context *ctx) +{ + ovsdb_idl_add_column(ctx->idl, &nbrec_logical_router_port_col_name); + ovsdb_idl_add_column(ctx->idl, &nbrec_logical_router_port_col_options); +} + +static void +nbctl_lrp_set_options(struct ctl_context *ctx) +{ + const char *id = ctx->argv[1]; + const struct nbrec_logical_router_port *lrp = NULL; + size_t i; + struct smap options = SMAP_INITIALIZER(&options); + + char *error = lrp_by_name_or_uuid(ctx, id, true, &lrp); + if (error) { + ctx->error = error; + return; + } + for (i = 2; i < ctx->argc; i++) { + char *key, *value; + value = xstrdup(ctx->argv[i]); + key = strsep(&value, "="); + if (value) { + smap_add(&options, key, value); + } + free(key); + } + + nbrec_logical_router_port_set_options(lrp, &options); + + smap_destroy(&options); +} + /* Removes logical router port 'lrp->gateway_chassis[idx]'. */ static void remove_gc(const struct nbrec_logical_router_port *lrp, size_t idx) @@ -5857,6 +5930,7 @@ route_cmp_details(const struct nbrec_logical_router_static_route *r1, } return r1->output_port ? 1 : -1; } + struct ipv4_route { int priority; ovs_be32 addr; @@ -5866,6 +5940,11 @@ struct ipv4_route { static int __ipv4_route_cmp(const struct ipv4_route *r1, const struct ipv4_route *r2) { + int rtb_cmp = strcmp(r1->route->route_table, + r2->route->route_table); + if (rtb_cmp) { + return rtb_cmp; + } if (r1->priority != r2->priority) { return r1->priority > r2->priority ? -1 : 1; } @@ -5897,6 +5976,11 @@ struct ipv6_route { static int __ipv6_route_cmp(const struct ipv6_route *r1, const struct ipv6_route *r2) { + int rtb_cmp = strcmp(r1->route->route_table, + r2->route->route_table); + if (rtb_cmp) { + return rtb_cmp; + } if (r1->priority != r2->priority) { return r1->priority > r2->priority ? -1 : 1; } @@ -5978,6 +6062,8 @@ nbctl_pre_lr_route_list(struct ctl_context *ctx) &nbrec_logical_router_static_route_col_options); ovsdb_idl_add_column(ctx->idl, &nbrec_logical_router_static_route_col_bfd); + ovsdb_idl_add_column(ctx->idl, + &nbrec_logical_router_static_route_col_route_table); } static void @@ -6041,6 +6127,7 @@ nbctl_lr_route_list(struct ctl_context *ctx) if (n_ipv4_routes) { ds_put_cstr(&ctx->output, "IPv4 Routes\n"); } + const struct nbrec_logical_router_static_route *route; for (int i = 0; i < n_ipv4_routes; i++) { bool ecmp = false; if (i < n_ipv4_routes - 1 && @@ -6051,6 +6138,15 @@ nbctl_lr_route_list(struct ctl_context *ctx) &ipv4_routes[i - 1])) { ecmp = true; } + + route = ipv4_routes[i].route; + if (!i || (i > 0 && strcmp(route->route_table, + ipv4_routes[i - 1].route->route_table))) { + ds_put_format(&ctx->output, "%sRoute Table %s:\n", i ? "\n" : "", + strlen(route->route_table) ? route->route_table + : "global"); + } + print_route(ipv4_routes[i].route, &ctx->output, ecmp); } @@ -6068,6 +6164,15 @@ nbctl_lr_route_list(struct ctl_context *ctx) &ipv6_routes[i - 1])) { ecmp = true; } + + route = ipv6_routes[i].route; + if (!i || (i > 0 && strcmp(route->route_table, + ipv6_routes[i - 1].route->route_table))) { + ds_put_format(&ctx->output, "%sRoute Table %s:\n", i ? "\n" : "", + strlen(route->route_table) ? route->route_table + : "global"); + } + print_route(ipv6_routes[i].route, &ctx->output, ecmp); } @@ -6886,6 +6991,8 @@ static const struct ctl_command_syntax nbctl_commands[] = { "PORT CHASSIS [PRIORITY]", nbctl_pre_lrp_set_gateway_chassis, nbctl_lrp_set_gateway_chassis, NULL, "--may-exist", RW }, + { "lrp-set-options", 1, INT_MAX, "PORT KEY=VALUE [KEY=VALUE]...", + nbctl_pre_lrp_options, nbctl_lrp_set_options, NULL, "", RW }, { "lrp-del-gateway-chassis", 2, 2, "PORT CHASSIS", nbctl_pre_lrp_del_gateway_chassis, nbctl_lrp_del_gateway_chassis, NULL, "", RW }, @@ -6909,10 +7016,11 @@ static const struct ctl_command_syntax nbctl_commands[] = { /* logical router route commands. */ { "lr-route-add", 3, 4, "ROUTER PREFIX NEXTHOP [PORT]", nbctl_pre_lr_route_add, nbctl_lr_route_add, NULL, - "--may-exist,--ecmp,--ecmp-symmetric-reply,--policy=,--bfd?", RW }, + "--may-exist,--ecmp,--ecmp-symmetric-reply,--policy=,--route-table=,--bfd?", + RW }, { "lr-route-del", 1, 4, "ROUTER [PREFIX [NEXTHOP [PORT]]]", nbctl_pre_lr_route_del, nbctl_lr_route_del, NULL, - "--if-exists,--policy=", RW }, + "--if-exists,--policy=,--route-table=", RW }, { "lr-route-list", 1, 1, "ROUTER", nbctl_pre_lr_route_list, nbctl_lr_route_list, NULL, "", RO },