Received: by 2002:a05:7412:37c9:b0:e2:908c:2ebd with SMTP id jz9csp874797rdb; Tue, 19 Sep 2023 12:48:14 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGK2BNegfrFGWlEbnzoZlOXn2lGLoihXSGmt3eDGBm9G7zGilCU2g5d5X22KqBTQzUE8572 X-Received: by 2002:a17:90a:930d:b0:262:fc8a:ed1 with SMTP id p13-20020a17090a930d00b00262fc8a0ed1mr614843pjo.44.1695152894076; Tue, 19 Sep 2023 12:48:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695152894; cv=none; d=google.com; s=arc-20160816; b=IMDfV7ZJVctsspbrUdx8JTnZNaPZ0hB0SoKzZK4oxx+2S726OxaRqk0jwrGnXdD3ht 0jFHRcJV8TWvkMdfOfy0xSCHqTEsW/mpjdBDbomcmPZ/WgSvCD+rDOk3xBOgyo5RyfJf YcMQgoYMB34Ci2CSIQeNPOQLwP7E36Xxb4cO8nAkaUg96qEchAapHI0VxZo2Y9VincqL dFO94McxYOsM0HoIcIAEX+UmHhcEycn1NJs12K2Hto+hOW06H/OdxObQ642TcQUbb/cp PRT93WrO67wgxXazXZIs2GVsmUCdlBnMN/HCvLimjlkQJuS7asKJQNEYNLGdv2l2AK87 GGpg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:in-reply-to:references:message-id :content-transfer-encoding:mime-version:subject:date:from :dkim-signature; bh=kU8HBxwMiHoraAYfQU4wgo1OEMx7KTjr6zXihHrPF04=; fh=vdy8fLmkzgLosg2v5sVYMftPpjJTf1v+KansN80xFQ8=; b=Q/FllKsDKLR+181lfTdCu7O8Zpe97nRL6E4bOPeAo7uq1f/U7feWlxLLILTXnUYTIl /ZwjJRU2mlFqfR5JYjwHRU6ybVFZvul8RdJQA9q9YGiC+E1DzMiDFkR2XsuWrsJJ9JRm h1KHrhNAaAVb9iPT2UAQaQNF4v5ZqSTtHIyvmTJW4b4JWOG//Nnyk3pAX9RIUTm/K+Tw mUdRn5RKIaiVBi/j8//fvNLTuwZF/noVJqdtXwWKP5NatS92ypd9ASmRxKcDai/VszAy uXhMFGinFQh81wJb78vR+Q/g8UePH+XISq6ZOZk448DNm2Q5rWCbiMuGc47p8zlgo3GO sG6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@avm.de header.s=mail header.b=M+XuX7K0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:1 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=avm.de Return-Path: Received: from morse.vger.email (morse.vger.email. [2620:137:e000::3:1]) by mx.google.com with ESMTPS id t11-20020a17090a5d8b00b00263a923c189si9817213pji.100.2023.09.19.12.48.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Sep 2023 12:48:14 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:1 as permitted sender) client-ip=2620:137:e000::3:1; Authentication-Results: mx.google.com; dkim=pass header.i=@avm.de header.s=mail header.b=M+XuX7K0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:1 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=avm.de Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by morse.vger.email (Postfix) with ESMTP id 3FFDA80E6C6B; Tue, 19 Sep 2023 05:18:26 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at morse.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232078AbjISMSQ (ORCPT + 99 others); Tue, 19 Sep 2023 08:18:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231799AbjISMRa (ORCPT ); Tue, 19 Sep 2023 08:17:30 -0400 Received: from mail.avm.de (mail.avm.de [212.42.244.94]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D0814E3; Tue, 19 Sep 2023 05:16:44 -0700 (PDT) Received: from mail-auth.avm.de (dovecot-mx-01.avm.de [212.42.244.71]) by mail.avm.de (Postfix) with ESMTPS; Tue, 19 Sep 2023 14:16:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=avm.de; s=mail; t=1695125795; bh=1Pn1Mj5B9BK9G6xRh+VXmW7e+DczI+9uJJqpPrAiqOA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=M+XuX7K00vctJxIPrf1FQDGQdyJWQVco7pMmtmaGPUVYmHGhE2ANt7WGaXd1GFpWI sTuq6gICoVsbC4Q1xW15L4TecDWhmBTrqo56zFQHNWLIGAusW5Lvx7Xe2dquMLQU1k QG2qtj2NusTAgxYBfh4hUrKWNWuK0t1WuoYiAR5s= Received: from localhost (unknown [172.17.88.63]) by mail-auth.avm.de (Postfix) with ESMTPSA id D5AC682000; Tue, 19 Sep 2023 14:16:34 +0200 (CEST) From: Johannes Nixdorf Date: Tue, 19 Sep 2023 10:12:53 +0200 Subject: [PATCH net-next v4 6/6] selftests: forwarding: bridge_fdb_learning_limit: Add a new selftest MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20230919-fdb_limit-v4-6-39f0293807b8@avm.de> References: <20230919-fdb_limit-v4-0-39f0293807b8@avm.de> In-Reply-To: <20230919-fdb_limit-v4-0-39f0293807b8@avm.de> To: "David S. Miller" , Andrew Lunn , David Ahern , Eric Dumazet , Florian Fainelli , Ido Schimmel , Jakub Kicinski , Nikolay Aleksandrov , Oleksij Rempel , Paolo Abeni , Roopa Prabhu , Shuah Khan , Vladimir Oltean Cc: bridge@lists.linux-foundation.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Johannes Nixdorf X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1695111167; l=7286; i=jnixdorf-oss@avm.de; s=20230906; h=from:subject:message-id; bh=1Pn1Mj5B9BK9G6xRh+VXmW7e+DczI+9uJJqpPrAiqOA=; b=ZSgDZskCJzluT9nSnnXD2U5tXzeWhEqArbAtQ1bb9jVX8f9JbxWL9ssQ0ZSe5OroeeKh3G4Ck 1MHUzy2/ZwZDCMw5QOzDHvmilgHtKhAmtFrHV4eBea87U1un1lvT6Dr X-Developer-Key: i=jnixdorf-oss@avm.de; a=ed25519; pk=KMraV4q7ANHRrwjf9EVhvU346JsqGGNSbPKeNILOQfo= X-purgate-ID: 149429::1695125795-4DE39EEA-8F192E7E/0/0 X-purgate-type: clean X-purgate-size: 7288 X-purgate-Ad: Categorized by eleven eXpurgate (R) http://www.eleven.de X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate: clean X-Spam-Status: No, score=0.2 required=5.0 tests=DATE_IN_PAST_03_06, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on morse.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (morse.vger.email [0.0.0.0]); Tue, 19 Sep 2023 05:18:26 -0700 (PDT) Add a suite covering the fdb_n_learned and fdb_max_learned bridge features, touching all special cases in accounting at least once. Signed-off-by: Johannes Nixdorf --- tools/testing/selftests/net/forwarding/Makefile | 3 +- .../net/forwarding/bridge_fdb_learning_limit.sh | 283 +++++++++++++++++++++ 2 files changed, 285 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/forwarding/Makefile b/tools/testing/selftests/net/forwarding/Makefile index 74e754e266c3..df593b7b3e6b 100644 --- a/tools/testing/selftests/net/forwarding/Makefile +++ b/tools/testing/selftests/net/forwarding/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ OR MIT -TEST_PROGS = bridge_igmp.sh \ +TEST_PROGS = bridge_fdb_learning_limit.sh \ + bridge_igmp.sh \ bridge_locked_port.sh \ bridge_mdb.sh \ bridge_mdb_host.sh \ diff --git a/tools/testing/selftests/net/forwarding/bridge_fdb_learning_limit.sh b/tools/testing/selftests/net/forwarding/bridge_fdb_learning_limit.sh new file mode 100755 index 000000000000..0760a34b7114 --- /dev/null +++ b/tools/testing/selftests/net/forwarding/bridge_fdb_learning_limit.sh @@ -0,0 +1,283 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +# ShellCheck incorrectly believes that most of the code here is unreachable +# because it's invoked by variable name following ALL_TESTS. +# +# shellcheck disable=SC2317 + +ALL_TESTS="check_accounting check_limit" +NUM_NETIFS=6 +source lib.sh + +TEST_MAC_BASE=de:ad:be:ef:42: + +NUM_PKTS=16 +FDB_LIMIT=8 + +FDB_TYPES=( + # name is counted? overrides learned? + 'learned 1 0' + 'static 0 1' + 'user 0 1' + 'extern_learn 0 1' + 'local 0 1' +) + +mac() +{ + printf "${TEST_MAC_BASE}%02x" "$1" +} + +H1_DEFAULT_MAC=$(mac 42) + +switch_create() +{ + ip link add dev br0 type bridge + + ip link set dev "$swp1" master br0 + ip link set dev "$swp2" master br0 + # swp3 is used to add local MACs, so do not add it to the bridge yet. + + # swp2 is only used for replying when learning on swp1, its MAC should not be learned. + ip link set dev "$swp2" type bridge_slave learning off + + ip link set dev br0 up + + ip link set dev "$swp1" up + ip link set dev "$swp2" up + ip link set dev "$swp3" up +} + +switch_destroy() +{ + ip link set dev "$swp3" down + ip link set dev "$swp2" down + ip link set dev "$swp1" down + + ip link del dev br0 +} + +h_create() +{ + ip link set "$h1" addr "$H1_DEFAULT_MAC" + + simple_if_init "$h1" 192.0.2.1/24 + simple_if_init "$h2" 192.0.2.2/24 +} + +h_destroy() +{ + simple_if_fini "$h1" 192.0.2.1/24 + simple_if_fini "$h2" 192.0.2.2/24 +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + h2=${NETIFS[p3]} + swp2=${NETIFS[p4]} + + swp3=${NETIFS[p6]} + + vrf_prepare + + h_create + + switch_create +} + +cleanup() +{ + pre_cleanup + + switch_destroy + + h_destroy + + vrf_cleanup +} + +fdb_get_n_learned() +{ + ip -d -j link show dev br0 type bridge | \ + jq '.[]["linkinfo"]["info_data"]["fdb_n_learned"]' +} + +fdb_get_n_mac() +{ + local mac=${1} + + bridge -j fdb show br br0 | \ + jq "map(select(.mac == \"${mac}\" and (has(\"vlan\") | not))) | length" +} + +fdb_fill_learned() +{ + local i + + for i in $(seq 1 "$NUM_PKTS"); do + fdb_add learned "$(mac "$i")" + done +} + +fdb_reset() +{ + bridge fdb flush dev br0 + + # Keep the default MAC address of h1 in the table. We set it to a different one when + # testing dynamic learning. + bridge fdb add "$H1_DEFAULT_MAC" dev "$swp1" master static use +} + +fdb_add() +{ + local type=$1 mac=$2 + + case "$type" in + learned) + ip link set "$h1" addr "$mac" + # Wait for a reply so we implicitly wait until after the forwarding + # code finished and the FDB entry was created. + PING_COUNT=1 ping_do "$h1" 192.0.2.2 + check_err $? "Failed to ping another bridge port" + ip link set "$h1" addr "$H1_DEFAULT_MAC" + ;; + local) + ip link set dev "$swp3" addr "$mac" && ip link set "$swp3" master br0 + ;; + static) + bridge fdb replace "$mac" dev "$swp1" master static + ;; + user) + bridge fdb replace "$mac" dev "$swp1" master static use + ;; + extern_learn) + bridge fdb replace "$mac" dev "$swp1" master extern_learn + ;; + esac + + check_err $? "Failed to add a FDB entry of type ${type}" +} + +fdb_del() +{ + local type=$1 mac=$2 + + case "$type" in + local) + ip link set "$swp3" nomaster + ;; + *) + bridge fdb del "$mac" dev "$swp1" master + ;; + esac + + check_err $? "Failed to remove a FDB entry of type ${type}" +} + +check_accounting_one_type() +{ + local type=$1 is_counted=$2 overrides_learned=$3 + shift 3 + RET=0 + + fdb_reset + fdb_add "$type" "$(mac 0)" + learned=$(fdb_get_n_learned) + [ "$learned" -ne "$is_counted" ] + check_fail $? "Inserted FDB type ${type}: Expected the count ${is_counted}, but got ${learned}" + + fdb_del "$type" "$(mac 0)" + learned=$(fdb_get_n_learned) + [ "$learned" -ne 0 ] + check_fail $? "Removed FDB type ${type}: Expected the count 0, but got ${learned}" + + if [ "$overrides_learned" -eq 1 ]; then + fdb_reset + fdb_add learned "$(mac 0)" + fdb_add "$type" "$(mac 0)" + learned=$(fdb_get_n_learned) + [ "$learned" -ne "$is_counted" ] + check_fail $? "Set a learned entry to FDB type ${type}: Expected the count ${is_counted}, but got ${learned}" + fdb_del "$type" "$(mac 0)" + fi + + log_test "FDB accounting interacting with FDB type ${type}" +} + +check_accounting() +{ + local type_args learned + RET=0 + + fdb_reset + learned=$(fdb_get_n_learned) + [ "$learned" -ne 0 ] + check_fail $? "Flushed the FDB table: Expected the count 0, but got ${learned}" + + fdb_fill_learned + sleep 1 + + learned=$(fdb_get_n_learned) + [ "$learned" -ne "$NUM_PKTS" ] + check_fail $? "Filled the FDB table: Expected the count ${NUM_PKTS}, but got ${learned}" + + log_test "FDB accounting" + + for type_args in "${FDB_TYPES[@]}"; do + # This is intentional use of word splitting. + # shellcheck disable=SC2086 + check_accounting_one_type $type_args + done +} + +check_limit_one_type() +{ + local type=$1 is_counted=$2 + local n_mac expected=$((1 - is_counted)) + RET=0 + + fdb_reset + fdb_fill_learned + + fdb_add "$type" "$(mac 0)" + n_mac=$(fdb_get_n_mac "$(mac 0)") + [ "$n_mac" -ne "$expected" ] + check_fail $? "Inserted FDB type ${type} at limit: Expected the count ${expected}, but got ${n_mac}" + + log_test "FDB limits interacting with FDB type ${type}" +} + +check_limit() +{ + local learned + RET=0 + + ip link set br0 type bridge fdb_max_learned "$FDB_LIMIT" + + fdb_reset + fdb_fill_learned + + learned=$(fdb_get_n_learned) + [ "$learned" -ne "$FDB_LIMIT" ] + check_fail $? "Filled the limited FDB table: Expected the count ${FDB_LIMIT}, but got ${learned}" + + log_test "FDB limits" + + for type_args in "${FDB_TYPES[@]}"; do + # This is intentional use of word splitting. + # shellcheck disable=SC2086 + check_limit_one_type $type_args + done +} + +trap cleanup EXIT + +setup_prepare + +tests_run + +exit $EXIT_STATUS -- 2.42.0