diff mbox series

[v7,net-next,9/9] selftests: forwarding: add test of MAC-Auth Bypass to locked port tests

Message ID 20221009174052.1927483-10-netdev@kapio-technology.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series Extend locked port feature with FDB locked flag (MAC-Auth/MAB) | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 1 maintainers not CCed: liuhangbin@gmail.com
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success net selftest script(s) already in Makefile
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch warning WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? WARNING: line length of 81 exceeds 80 columns WARNING: line length of 85 exceeds 80 columns WARNING: line length of 87 exceeds 80 columns WARNING: line length of 89 exceeds 80 columns WARNING: line length of 90 exceeds 80 columns WARNING: line length of 93 exceeds 80 columns WARNING: line length of 95 exceeds 80 columns WARNING: line length of 98 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Hans Schultz Oct. 9, 2022, 5:40 p.m. UTC
Verify that the MAC-Auth mechanism works by adding a FDB entry with the
locked flag set, denying access until the FDB entry is replaced with a
FDB entry without the locked flag set.

Add test of blackhole fdb entries, verifying that there is no forwarding
to a blackhole entry from any port, and that the blackhole entry can be
replaced.

Also add a test that verifies that sticky FDB entries cannot roam (this
is not needed for now, but should in general be present anyhow for future
applications).

Signed-off-by: Hans J. Schultz <netdev@kapio-technology.com>
---
 .../selftests/drivers/net/dsa/Makefile        |   1 +
 .../testing/selftests/net/forwarding/Makefile |   1 +
 .../net/forwarding/bridge_blackhole_fdb.sh    | 134 ++++++++++++++++++
 .../net/forwarding/bridge_locked_port.sh      | 101 ++++++++++++-
 tools/testing/selftests/net/forwarding/lib.sh |  17 +++
 5 files changed, 253 insertions(+), 1 deletion(-)
 create mode 100755 tools/testing/selftests/net/forwarding/bridge_blackhole_fdb.sh

Comments

Hans Schultz Oct. 12, 2022, 9:46 a.m. UTC | #1
On 2022-10-09 19:40, Hans J. Schultz wrote:
> Verify that the MAC-Auth mechanism works by adding a FDB entry with the
> locked flag set, denying access until the FDB entry is replaced with a
> FDB entry without the locked flag set.
> 
> Add test of blackhole fdb entries, verifying that there is no 
> forwarding
> to a blackhole entry from any port, and that the blackhole entry can be
> replaced.
> 

Ido, have you had time to look at this patch set, and do I need to 
release a v8 to fix those two forgotten statics and maybe also this new 
switchcore driver that was not there when I posted this patch set?
Ido Schimmel Oct. 13, 2022, 12:06 p.m. UTC | #2
On Sun, Oct 09, 2022 at 07:40:52PM +0200, Hans J. Schultz wrote:
> +locked_port_mab()
> +{
> +	RET=0
> +	check_port_mab_support || return 0
> +
> +	ping_do $h1 192.0.2.2
> +	check_err $? "MAB: Ping did not work before locking port"
> +
> +	bridge link set dev $swp1 locked on mab on
> +
> +	ping_do $h1 192.0.2.2
> +	check_fail $? "MAB: Ping worked on mab enabled port without FDB entry"
> +
> +	bridge fdb get `mac_get $h1` vlan 1 dev $swp1 | grep "dev $swp1 vlan 1" | grep -q "locked"
> +	check_err $? "MAB: No locked FDB entry after ping on mab enabled port"
> +
> +	bridge fdb replace `mac_get $h1` dev $swp1 master static
> +
> +	ping_do $h1 192.0.2.2
> +	check_err $? "MAB: Ping did not work with FDB entry without locked flag"
> +
> +	bridge fdb del `mac_get $h1` dev $swp1 master
> +	bridge link set dev $swp1 locked off mab off
> +
> +	log_test "Locked port MAB"
> +}
> +
> +# Check that entries cannot roam from an unlocked port to a locked port.
> +locked_port_station_move()
> +{
> +	local mac=a0:b0:c0:c0:b0:a0
> +
> +	RET=0
> +	check_locked_port_support || return 0
> +
> +	bridge link set dev $swp1 locked on learning on
> +
> +	$MZ $h1 -q -c 5 -d 100msec -t udp -a $mac -b rand
> +	bridge fdb show dev $swp1 | grep -q $mac
> +	check_fail $? "Locked port station move: FDB entry on first injection"
> +
> +	$MZ $h2 -q -c 5 -d 100msec -t udp -a $mac -b rand
> +	bridge fdb get $mac vlan 1 dev $swp2 | grep "dev $swp2 vlan 1" | grep -q "master br0"
> +	check_err $? "Locked port station move: Entry not found on unlocked port"
> +
> +	$MZ $h1 -q -c 5 -d 100msec -t udp -a $mac -b rand
> +	bridge fdb get $mac vlan 1 dev $swp1 | grep "dev $swp1 vlan 1" | grep -q "master br0"
> +	check_fail $? "Locked port station move: entry roamed to locked port"
> +
> +	bridge fdb del $mac vlan 1 dev $swp2 master
> +	bridge link set dev $swp1 locked off learning off
> +
> +	log_test "Locked port station move"
> +}
> +
> +# Roaming to and from a MAB enabled port should work if blackhole flag is not set
> +locked_port_mab_station_move()
> +{
> +	local mac=10:20:30:30:20:10
> +
> +	RET=0
> +	check_port_mab_support || return 0
> +
> +	bridge link set dev $swp1 locked on mab on
> +
> +	$MZ $h1 -q -c 5 -d 100 mesc -t udp -a $mac -b rand
> +	if bridge fdb show dev $swp1 | grep "$mac vlan 1" | grep -q "blackhole"; then
> +		echo "SKIP: Roaming not possible with blackhole flag, skipping test..."
> +		bridge link set dev $swp1 locked off mab off
> +		return $ksft_skip
> +	fi
> +
> +	bridge fdb show dev $swp1 | grep "$mac vlan 1" | grep -q "locked"
> +	check_err $? "MAB station move: no locked entry on first injection"
> +
> +	$MZ $h2 -q -c 5 -d 100msec -t udp -a $mac -b rand
> +	bridge fdb get $mac vlan 1 dev $swp1 | grep "dev $swp1 vlan 1" | grep -q "locked"
> +	check_fail $? "MAB station move: locked entry did not move"
> +
> +	bridge fdb get $mac vlan 1 dev $swp2 | grep "dev $swp2 vlan 1" | grep -q "locked"
> +	check_fail $? "MAB station move: roamed entry to unlocked port had locked flag on"
> +
> +	bridge fdb get $mac vlan 1 dev $swp2 | grep "dev $swp2 vlan 1" | grep -q "master br0"
> +	check_err $? "MAB station move: roamed entry not found"
> +
> +	bridge fdb del $mac vlan 1 dev $swp2 master
> +	bridge link set dev $swp1 locked off mab off
> +
> +	log_test "Locked port MAB station move"
> +}

Looks OK to me. I made some change to make sure we are using "bridge fdb
get" in a consistent manner instead of relying on iproute2 dump output
too much. Please consider including them in the next version.

FYI, I ran your version and mine with veth pairs and both are OK.

diff --git a/tools/testing/selftests/net/forwarding/bridge_locked_port.sh b/tools/testing/selftests/net/forwarding/bridge_locked_port.sh
index fbe558f25e44..f0bc0bcbc246 100755
--- a/tools/testing/selftests/net/forwarding/bridge_locked_port.sh
+++ b/tools/testing/selftests/net/forwarding/bridge_locked_port.sh
@@ -187,7 +187,7 @@ locked_port_mab()
 	ping_do $h1 192.0.2.2
 	check_fail $? "MAB: Ping worked on mab enabled port without FDB entry"
 
-	bridge fdb get `mac_get $h1` vlan 1 dev $swp1 | grep "dev $swp1 vlan 1" | grep -q "locked"
+	bridge fdb get `mac_get $h1` br br0 vlan 1 | grep "dev $swp1" | grep -q "locked"
 	check_err $? "MAB: No locked FDB entry after ping on mab enabled port"
 
 	bridge fdb replace `mac_get $h1` dev $swp1 master static
@@ -212,15 +212,15 @@ locked_port_station_move()
 	bridge link set dev $swp1 locked on learning on
 
 	$MZ $h1 -q -c 5 -d 100msec -t udp -a $mac -b rand
-	bridge fdb show dev $swp1 | grep -q $mac
+	bridge fdb get $mac br br0 vlan 1 &> /dev/null
 	check_fail $? "Locked port station move: FDB entry on first injection"
 
 	$MZ $h2 -q -c 5 -d 100msec -t udp -a $mac -b rand
-	bridge fdb get $mac vlan 1 dev $swp2 | grep "dev $swp2 vlan 1" | grep -q "master br0"
+	bridge fdb get $mac br br0 vlan 1 | grep -q "dev $swp2"
 	check_err $? "Locked port station move: Entry not found on unlocked port"
 
 	$MZ $h1 -q -c 5 -d 100msec -t udp -a $mac -b rand
-	bridge fdb get $mac vlan 1 dev $swp1 | grep "dev $swp1 vlan 1" | grep -q "master br0"
+	bridge fdb get $mac br br0 vlan 1 | grep -q "dev $swp1"
 	check_fail $? "Locked port station move: entry roamed to locked port"
 
 	bridge fdb del $mac vlan 1 dev $swp2 master
@@ -229,7 +229,8 @@ locked_port_station_move()
 	log_test "Locked port station move"
 }
 
-# Roaming to and from a MAB enabled port should work if blackhole flag is not set
+# Check that entries can roam from a locked port if blackhole FDB flag is not
+# set.
 locked_port_mab_station_move()
 {
 	local mac=10:20:30:30:20:10
@@ -246,19 +247,16 @@ locked_port_mab_station_move()
 		return $ksft_skip
 	fi
 
-	bridge fdb show dev $swp1 | grep "$mac vlan 1" | grep -q "locked"
+	bridge fdb get $mac br br0 vlan 1 | grep "dev $swp1" | grep -q "locked"
 	check_err $? "MAB station move: no locked entry on first injection"
 
 	$MZ $h2 -q -c 5 -d 100msec -t udp -a $mac -b rand
-	bridge fdb get $mac vlan 1 dev $swp1 | grep "dev $swp1 vlan 1" | grep -q "locked"
-	check_fail $? "MAB station move: locked entry did not move"
+	bridge fdb get $mac br br0 vlan 1 | grep -q "dev $swp2"
+	check_err $? "MAB station move: roamed entry not found"
 
-	bridge fdb get $mac vlan 1 dev $swp2 | grep "dev $swp2 vlan 1" | grep -q "locked"
+	bridge fdb get $mac br br0 vlan 1 | grep -q "locked"
 	check_fail $? "MAB station move: roamed entry to unlocked port had locked flag on"
 
-	bridge fdb get $mac vlan 1 dev $swp2 | grep "dev $swp2 vlan 1" | grep -q "master br0"
-	check_err $? "MAB station move: roamed entry not found"
-
 	bridge fdb del $mac vlan 1 dev $swp2 master
 	bridge link set dev $swp1 locked off mab off
Ido Schimmel Oct. 13, 2022, 12:16 p.m. UTC | #3
On Sun, Oct 09, 2022 at 07:40:52PM +0200, Hans J. Schultz wrote:
> +++ b/tools/testing/selftests/net/forwarding/bridge_blackhole_fdb.sh
> @@ -0,0 +1,134 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +
> +ALL_TESTS="blackhole_fdb"
> +NUM_NETIFS=4
> +source tc_common.sh
> +source lib.sh
> +
> +h1_create()
> +{
> +	simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
> +	vlan_create $h1 100 v$h1 198.51.100.1/24
> +}
> +
> +h1_destroy()
> +{
> +	vlan_destroy $h1 100
> +	simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
> +}
> +
> +h2_create()
> +{
> +	simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/64
> +	vlan_create $h2 100 v$h2 198.51.100.2/24
> +}
> +
> +h2_destroy()
> +{
> +	vlan_destroy $h2 100
> +	simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/64
> +}

There is unnecessary configuration here. Can be simplified:

diff --git a/tools/testing/selftests/net/forwarding/bridge_blackhole_fdb.sh b/tools/testing/selftests/net/forwarding/bridge_blackhole_fdb.sh
index 77d166180bc4..cc2145ea1968 100755
--- a/tools/testing/selftests/net/forwarding/bridge_blackhole_fdb.sh
+++ b/tools/testing/selftests/net/forwarding/bridge_blackhole_fdb.sh
@@ -8,26 +8,22 @@ source lib.sh
 
 h1_create()
 {
-	simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
-	vlan_create $h1 100 v$h1 198.51.100.1/24
+	simple_if_init $h1 192.0.2.1/24
 }
 
 h1_destroy()
 {
-	vlan_destroy $h1 100
-	simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
+	simple_if_fini $h1 192.0.2.1/24
 }
 
 h2_create()
 {
-	simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/64
-	vlan_create $h2 100 v$h2 198.51.100.2/24
+	simple_if_init $h2 192.0.2.2/24
 }
 
 h2_destroy()
 {
-	vlan_destroy $h2 100
-	simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/64
+	simple_if_fini $h2 192.0.2.2/24
 }
 
 switch_create()

> +
> +switch_create()
> +{
> +	ip link add dev br0 type bridge vlan_filtering 1
> +
> +	ip link set dev $swp1 master br0
> +	ip link set dev $swp2 master br0
> +
> +	ip link set dev br0 up
> +	ip link set dev $swp1 up
> +	ip link set dev $swp2 up
> +
> +	tc qdisc add dev $swp2 clsact
> +}
> +
> +switch_destroy()
> +{
> +	tc qdisc del dev $swp2 clsact
> +
> +	ip link set dev $swp2 down
> +	ip link set dev $swp1 down
> +
> +	ip link del dev br0
> +}
> +
> +setup_prepare()
> +{
> +	h1=${NETIFS[p1]}
> +	swp1=${NETIFS[p2]}
> +	h2=${NETIFS[p3]}
> +	swp2=${NETIFS[p4]}
> +
> +	vrf_prepare
> +
> +	h1_create
> +	h2_create
> +
> +	switch_create
> +}
> +
> +cleanup()
> +{
> +	pre_cleanup
> +
> +	switch_destroy
> +
> +	h2_destroy
> +	h1_destroy
> +
> +	vrf_cleanup
> +}
> +
> +# Check that there is no egress with blackhole entry and that blackhole entries can be replaced

Wrap this to 80 columns:

# Check that there is no egress with blackhole entry and that blackhole entries
# can be replaced.

> +blackhole_fdb()
> +{
> +	RET=0
> +
> +	check_blackhole_fdb_support || return 0
> +
> +	tc filter add dev $swp2 egress protocol ip pref 1 handle 1 flower \
> +		dst_ip 192.0.2.2 ip_proto udp dst_port 12345 action pass
> +
> +	$MZ $h1 -c 1 -p 128 -t udp "sp=54321,dp=12345" \
> +		-a own -b `mac_get $h2` -A 192.0.2.1 -B 192.0.2.2 -q
> +
> +	tc_check_packets "dev $swp2 egress" 1 1
> +	check_err $? "Packet not seen on egress before adding blackhole entry"
> +
> +	bridge fdb replace `mac_get $h2` dev br0 blackhole

vlan 1

> +	bridge fdb get `mac_get $h2` br br0 | grep -q blackhole

vlan 1

> +	check_err $? "Blackhole entry not found"
> +
> +	$MZ $h1 -c 1 -p 128 -t udp "sp=54321,dp=12345" \
> +		-a own -b `mac_get $h2` -A 192.0.2.1 -B 192.0.2.2 -q
> +
> +	tc_check_packets "dev $swp2 egress" 1 1
> +	check_err $? "Packet seen on egress after adding blackhole entry"
> +
> +	# Check blackhole entries can be replaced.
> +	bridge fdb replace `mac_get $h2` dev $swp2 master static

vlan 1

> +	bridge fdb get `mac_get $h2` br br0 | grep -q blackhole

vlan 1

> +	check_fail $? "Blackhole entry found after replacement"
> +
> +	$MZ $h1 -c 1 -p 128 -t udp "sp=54321,dp=12345" \
> +		-a own -b `mac_get $h2` -A 192.0.2.1 -B 192.0.2.2 -q
> +
> +	tc_check_packets "dev $swp2 egress" 1 2
> +	check_err $? "Packet not seen on egress after replacing blackhole entry"
> +
> +	bridge fdb del `mac_get $h2` dev $swp2 master static

vlan 1

> +	tc filter del dev $swp2 egress protocol ip pref 1 handle 1 flower
> +
> +	log_test "Blackhole FDB entry"
> +}

Tested with veth pairs. Looks OK to me.
Ido Schimmel Oct. 13, 2022, 2:28 p.m. UTC | #4
On Wed, Oct 12, 2022 at 11:46:55AM +0200, netdev@kapio-technology.com wrote:
> Ido, have you had time to look at this patch set, and do I need to release a
> v8 to fix those two forgotten statics and maybe also this new switchcore
> driver that was not there when I posted this patch set?

I don't know which changes you are referring to, but v8 should
incorporate all the changes requested so far. Do not post it as long as
net-next is closed (unless marked as RFC):

https://www.kernel.org/doc/html/latest/process/maintainer-netdev.html#how-often-do-changes-from-these-trees-make-it-to-the-mainline-linus-tree
Hans Schultz Oct. 13, 2022, 3:17 p.m. UTC | #5
On 2022-10-13 16:28, Ido Schimmel wrote:
> On Wed, Oct 12, 2022 at 11:46:55AM +0200, netdev@kapio-technology.com 
> wrote:
>> Ido, have you had time to look at this patch set, and do I need to 
>> release a
>> v8 to fix those two forgotten statics and maybe also this new 
>> switchcore
>> driver that was not there when I posted this patch set?
> 
> I don't know which changes you are referring to, but v8 should
> incorporate all the changes requested so far. Do not post it as long as
> net-next is closed (unless marked as RFC):

Ohh, I missed declaring two functions as static in chip.c, and 
unfortunately my compiler did not give me any warnings...

What is the schedule for net-next to be open (I guess that it is closed 
as of now)?

> 
> https://www.kernel.org/doc/html/latest/process/maintainer-netdev.html#how-often-do-changes-from-these-trees-make-it-to-the-mainline-linus-tree
Ido Schimmel Oct. 13, 2022, 6:13 p.m. UTC | #6
On Thu, Oct 13, 2022 at 05:17:42PM +0200, netdev@kapio-technology.com wrote:
> What is the schedule for net-next to be open (I guess that it is closed as
> of now)?

After the merge window closes and 6.1-rc1 is released. Probably on
Monday.
diff mbox series

Patch

diff --git a/tools/testing/selftests/drivers/net/dsa/Makefile b/tools/testing/selftests/drivers/net/dsa/Makefile
index c393e7b73805..c0a75d869763 100644
--- a/tools/testing/selftests/drivers/net/dsa/Makefile
+++ b/tools/testing/selftests/drivers/net/dsa/Makefile
@@ -1,6 +1,7 @@ 
 # SPDX-License-Identifier: GPL-2.0+ OR MIT
 
 TEST_PROGS = bridge_locked_port.sh \
+	bridge_blackhole_fdb.sh \
 	bridge_mdb.sh \
 	bridge_mld.sh \
 	bridge_vlan_aware.sh \
diff --git a/tools/testing/selftests/net/forwarding/Makefile b/tools/testing/selftests/net/forwarding/Makefile
index a9c5c1be5088..7d832020937f 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 \
+	bridge_blackhole_fdb.sh \
 	bridge_locked_port.sh \
 	bridge_mdb.sh \
 	bridge_mdb_port_down.sh \
diff --git a/tools/testing/selftests/net/forwarding/bridge_blackhole_fdb.sh b/tools/testing/selftests/net/forwarding/bridge_blackhole_fdb.sh
new file mode 100755
index 000000000000..77d166180bc4
--- /dev/null
+++ b/tools/testing/selftests/net/forwarding/bridge_blackhole_fdb.sh
@@ -0,0 +1,134 @@ 
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+ALL_TESTS="blackhole_fdb"
+NUM_NETIFS=4
+source tc_common.sh
+source lib.sh
+
+h1_create()
+{
+	simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
+	vlan_create $h1 100 v$h1 198.51.100.1/24
+}
+
+h1_destroy()
+{
+	vlan_destroy $h1 100
+	simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
+}
+
+h2_create()
+{
+	simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/64
+	vlan_create $h2 100 v$h2 198.51.100.2/24
+}
+
+h2_destroy()
+{
+	vlan_destroy $h2 100
+	simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/64
+}
+
+switch_create()
+{
+	ip link add dev br0 type bridge vlan_filtering 1
+
+	ip link set dev $swp1 master br0
+	ip link set dev $swp2 master br0
+
+	ip link set dev br0 up
+	ip link set dev $swp1 up
+	ip link set dev $swp2 up
+
+	tc qdisc add dev $swp2 clsact
+}
+
+switch_destroy()
+{
+	tc qdisc del dev $swp2 clsact
+
+	ip link set dev $swp2 down
+	ip link set dev $swp1 down
+
+	ip link del dev br0
+}
+
+setup_prepare()
+{
+	h1=${NETIFS[p1]}
+	swp1=${NETIFS[p2]}
+	h2=${NETIFS[p3]}
+	swp2=${NETIFS[p4]}
+
+	vrf_prepare
+
+	h1_create
+	h2_create
+
+	switch_create
+}
+
+cleanup()
+{
+	pre_cleanup
+
+	switch_destroy
+
+	h2_destroy
+	h1_destroy
+
+	vrf_cleanup
+}
+
+# Check that there is no egress with blackhole entry and that blackhole entries can be replaced
+blackhole_fdb()
+{
+	RET=0
+
+	check_blackhole_fdb_support || return 0
+
+	tc filter add dev $swp2 egress protocol ip pref 1 handle 1 flower \
+		dst_ip 192.0.2.2 ip_proto udp dst_port 12345 action pass
+
+	$MZ $h1 -c 1 -p 128 -t udp "sp=54321,dp=12345" \
+		-a own -b `mac_get $h2` -A 192.0.2.1 -B 192.0.2.2 -q
+
+	tc_check_packets "dev $swp2 egress" 1 1
+	check_err $? "Packet not seen on egress before adding blackhole entry"
+
+	bridge fdb replace `mac_get $h2` dev br0 blackhole
+	bridge fdb get `mac_get $h2` br br0 | grep -q blackhole
+	check_err $? "Blackhole entry not found"
+
+	$MZ $h1 -c 1 -p 128 -t udp "sp=54321,dp=12345" \
+		-a own -b `mac_get $h2` -A 192.0.2.1 -B 192.0.2.2 -q
+
+	tc_check_packets "dev $swp2 egress" 1 1
+	check_err $? "Packet seen on egress after adding blackhole entry"
+
+	# Check blackhole entries can be replaced.
+	bridge fdb replace `mac_get $h2` dev $swp2 master static
+	bridge fdb get `mac_get $h2` br br0 | grep -q blackhole
+	check_fail $? "Blackhole entry found after replacement"
+
+	$MZ $h1 -c 1 -p 128 -t udp "sp=54321,dp=12345" \
+		-a own -b `mac_get $h2` -A 192.0.2.1 -B 192.0.2.2 -q
+
+	tc_check_packets "dev $swp2 egress" 1 2
+	check_err $? "Packet not seen on egress after replacing blackhole entry"
+
+	bridge fdb del `mac_get $h2` dev $swp2 master static
+	tc filter del dev $swp2 egress protocol ip pref 1 handle 1 flower
+
+	log_test "Blackhole FDB entry"
+}
+
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+
+tests_run
+
+exit $EXIT_STATUS
diff --git a/tools/testing/selftests/net/forwarding/bridge_locked_port.sh b/tools/testing/selftests/net/forwarding/bridge_locked_port.sh
index 5b02b6b60ce7..fbe558f25e44 100755
--- a/tools/testing/selftests/net/forwarding/bridge_locked_port.sh
+++ b/tools/testing/selftests/net/forwarding/bridge_locked_port.sh
@@ -1,7 +1,15 @@ 
 #!/bin/bash
 # SPDX-License-Identifier: GPL-2.0
 
-ALL_TESTS="locked_port_ipv4 locked_port_ipv6 locked_port_vlan"
+ALL_TESTS="
+	locked_port_ipv4
+	locked_port_ipv6
+	locked_port_vlan
+	locked_port_mab
+	locked_port_station_move
+	locked_port_mab_station_move
+"
+
 NUM_NETIFS=4
 CHECK_TC="no"
 source lib.sh
@@ -166,6 +174,97 @@  locked_port_ipv6()
 	log_test "Locked port ipv6"
 }
 
+locked_port_mab()
+{
+	RET=0
+	check_port_mab_support || return 0
+
+	ping_do $h1 192.0.2.2
+	check_err $? "MAB: Ping did not work before locking port"
+
+	bridge link set dev $swp1 locked on mab on
+
+	ping_do $h1 192.0.2.2
+	check_fail $? "MAB: Ping worked on mab enabled port without FDB entry"
+
+	bridge fdb get `mac_get $h1` vlan 1 dev $swp1 | grep "dev $swp1 vlan 1" | grep -q "locked"
+	check_err $? "MAB: No locked FDB entry after ping on mab enabled port"
+
+	bridge fdb replace `mac_get $h1` dev $swp1 master static
+
+	ping_do $h1 192.0.2.2
+	check_err $? "MAB: Ping did not work with FDB entry without locked flag"
+
+	bridge fdb del `mac_get $h1` dev $swp1 master
+	bridge link set dev $swp1 locked off mab off
+
+	log_test "Locked port MAB"
+}
+
+# Check that entries cannot roam from an unlocked port to a locked port.
+locked_port_station_move()
+{
+	local mac=a0:b0:c0:c0:b0:a0
+
+	RET=0
+	check_locked_port_support || return 0
+
+	bridge link set dev $swp1 locked on learning on
+
+	$MZ $h1 -q -c 5 -d 100msec -t udp -a $mac -b rand
+	bridge fdb show dev $swp1 | grep -q $mac
+	check_fail $? "Locked port station move: FDB entry on first injection"
+
+	$MZ $h2 -q -c 5 -d 100msec -t udp -a $mac -b rand
+	bridge fdb get $mac vlan 1 dev $swp2 | grep "dev $swp2 vlan 1" | grep -q "master br0"
+	check_err $? "Locked port station move: Entry not found on unlocked port"
+
+	$MZ $h1 -q -c 5 -d 100msec -t udp -a $mac -b rand
+	bridge fdb get $mac vlan 1 dev $swp1 | grep "dev $swp1 vlan 1" | grep -q "master br0"
+	check_fail $? "Locked port station move: entry roamed to locked port"
+
+	bridge fdb del $mac vlan 1 dev $swp2 master
+	bridge link set dev $swp1 locked off learning off
+
+	log_test "Locked port station move"
+}
+
+# Roaming to and from a MAB enabled port should work if blackhole flag is not set
+locked_port_mab_station_move()
+{
+	local mac=10:20:30:30:20:10
+
+	RET=0
+	check_port_mab_support || return 0
+
+	bridge link set dev $swp1 locked on mab on
+
+	$MZ $h1 -q -c 5 -d 100 mesc -t udp -a $mac -b rand
+	if bridge fdb show dev $swp1 | grep "$mac vlan 1" | grep -q "blackhole"; then
+		echo "SKIP: Roaming not possible with blackhole flag, skipping test..."
+		bridge link set dev $swp1 locked off mab off
+		return $ksft_skip
+	fi
+
+	bridge fdb show dev $swp1 | grep "$mac vlan 1" | grep -q "locked"
+	check_err $? "MAB station move: no locked entry on first injection"
+
+	$MZ $h2 -q -c 5 -d 100msec -t udp -a $mac -b rand
+	bridge fdb get $mac vlan 1 dev $swp1 | grep "dev $swp1 vlan 1" | grep -q "locked"
+	check_fail $? "MAB station move: locked entry did not move"
+
+	bridge fdb get $mac vlan 1 dev $swp2 | grep "dev $swp2 vlan 1" | grep -q "locked"
+	check_fail $? "MAB station move: roamed entry to unlocked port had locked flag on"
+
+	bridge fdb get $mac vlan 1 dev $swp2 | grep "dev $swp2 vlan 1" | grep -q "master br0"
+	check_err $? "MAB station move: roamed entry not found"
+
+	bridge fdb del $mac vlan 1 dev $swp2 master
+	bridge link set dev $swp1 locked off mab off
+
+	log_test "Locked port MAB station move"
+}
+
 trap cleanup EXIT
 
 setup_prepare
diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh
index 3ffb9d6c0950..d6abe873665c 100755
--- a/tools/testing/selftests/net/forwarding/lib.sh
+++ b/tools/testing/selftests/net/forwarding/lib.sh
@@ -137,6 +137,23 @@  check_locked_port_support()
 	fi
 }
 
+check_port_mab_support()
+{
+	if ! bridge -d link show | grep -q "mab"; then
+		echo "SKIP: iproute2 too old; MacAuth feature not supported."
+		return $ksft_skip
+	fi
+}
+
+check_blackhole_fdb_support()
+{
+	bridge fdb help 2>&1|grep blackhole &> /dev/null
+	if [[ $? -ne 0 ]]; then
+		echo "SKIP: Blackhole fdb feature not supported."
+		return $ksft_skip
+	fi
+}
+
 if [[ "$(id -u)" -ne 0 ]]; then
 	echo "SKIP: need root privileges"
 	exit $ksft_skip