Skip to content

Commit 5003e52

Browse files
committed
Merge branch 'bonding-802-3ad-fix-no-transmission-of-lacpdus'
Jonathan Toppins says: ==================== bonding: 802.3ad: fix no transmission of LACPDUs Configuring a bond in a specific order can leave the bond in a state where it never transmits LACPDUs. The first patch adds some kselftest infrastructure and the reproducer that demonstrates the problem. The second patch fixes the issue. The new third patch makes ad_ticks_per_sec a static const and removes the passing of this variable via the stack. ==================== Link: https://lore.kernel.org/r/cover.1660919940.git.jtoppins@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 0ee7828 + f2e44df commit 5003e52

File tree

9 files changed

+108
-28
lines changed

9 files changed

+108
-28
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3679,6 +3679,7 @@ F: Documentation/networking/bonding.rst
36793679
F: drivers/net/bonding/
36803680
F: include/net/bond*
36813681
F: include/uapi/linux/if_bonding.h
3682+
F: tools/testing/selftests/net/bonding/
36823683

36833684
BOSCH SENSORTEC BMA400 ACCELEROMETER IIO DRIVER
36843685
M: Dan Robertson <dan@dlrobertson.com>

drivers/net/bonding/bond_3ad.c

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ enum ad_link_speed_type {
8484
static const u8 null_mac_addr[ETH_ALEN + 2] __long_aligned = {
8585
0, 0, 0, 0, 0, 0
8686
};
87-
static u16 ad_ticks_per_sec;
87+
88+
static const u16 ad_ticks_per_sec = 1000 / AD_TIMER_INTERVAL;
8889
static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
8990

9091
static const u8 lacpdu_mcast_addr[ETH_ALEN + 2] __long_aligned =
@@ -2001,36 +2002,24 @@ void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout)
20012002
/**
20022003
* bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures
20032004
* @bond: bonding struct to work on
2004-
* @tick_resolution: tick duration (millisecond resolution)
20052005
*
20062006
* Can be called only after the mac address of the bond is set.
20072007
*/
2008-
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
2008+
void bond_3ad_initialize(struct bonding *bond)
20092009
{
2010-
/* check that the bond is not initialized yet */
2011-
if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr),
2012-
bond->dev->dev_addr)) {
2013-
2014-
BOND_AD_INFO(bond).aggregator_identifier = 0;
2015-
2016-
BOND_AD_INFO(bond).system.sys_priority =
2017-
bond->params.ad_actor_sys_prio;
2018-
if (is_zero_ether_addr(bond->params.ad_actor_system))
2019-
BOND_AD_INFO(bond).system.sys_mac_addr =
2020-
*((struct mac_addr *)bond->dev->dev_addr);
2021-
else
2022-
BOND_AD_INFO(bond).system.sys_mac_addr =
2023-
*((struct mac_addr *)bond->params.ad_actor_system);
2024-
2025-
/* initialize how many times this module is called in one
2026-
* second (should be about every 100ms)
2027-
*/
2028-
ad_ticks_per_sec = tick_resolution;
2010+
BOND_AD_INFO(bond).aggregator_identifier = 0;
2011+
BOND_AD_INFO(bond).system.sys_priority =
2012+
bond->params.ad_actor_sys_prio;
2013+
if (is_zero_ether_addr(bond->params.ad_actor_system))
2014+
BOND_AD_INFO(bond).system.sys_mac_addr =
2015+
*((struct mac_addr *)bond->dev->dev_addr);
2016+
else
2017+
BOND_AD_INFO(bond).system.sys_mac_addr =
2018+
*((struct mac_addr *)bond->params.ad_actor_system);
20292019

2030-
bond_3ad_initiate_agg_selection(bond,
2031-
AD_AGGREGATOR_SELECTION_TIMER *
2032-
ad_ticks_per_sec);
2033-
}
2020+
bond_3ad_initiate_agg_selection(bond,
2021+
AD_AGGREGATOR_SELECTION_TIMER *
2022+
ad_ticks_per_sec);
20342023
}
20352024

20362025
/**

drivers/net/bonding/bond_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2081,7 +2081,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
20812081
/* Initialize AD with the number of times that the AD timer is called in 1 second
20822082
* can be called only after the mac address of the bond is set
20832083
*/
2084-
bond_3ad_initialize(bond, 1000/AD_TIMER_INTERVAL);
2084+
bond_3ad_initialize(bond);
20852085
} else {
20862086
SLAVE_AD_INFO(new_slave)->id =
20872087
SLAVE_AD_INFO(prev_slave)->id + 1;

include/net/bond_3ad.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ static inline const char *bond_3ad_churn_desc(churn_state_t state)
290290
}
291291

292292
/* ========== AD Exported functions to the main bonding code ========== */
293-
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution);
293+
void bond_3ad_initialize(struct bonding *bond);
294294
void bond_3ad_bind_slave(struct slave *slave);
295295
void bond_3ad_unbind_slave(struct slave *slave);
296296
void bond_3ad_state_machine_handler(struct work_struct *);

tools/testing/selftests/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ TARGETS += cpu-hotplug
1212
TARGETS += damon
1313
TARGETS += drivers/dma-buf
1414
TARGETS += drivers/s390x/uvdevice
15+
TARGETS += drivers/net/bonding
1516
TARGETS += efivarfs
1617
TARGETS += exec
1718
TARGETS += filesystems
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
# Makefile for net selftests
3+
4+
TEST_PROGS := bond-break-lacpdu-tx.sh
5+
6+
include ../../../lib.mk
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/bin/sh
2+
# SPDX-License-Identifier: GPL-2.0
3+
4+
# Regression Test:
5+
# Verify LACPDUs get transmitted after setting the MAC address of
6+
# the bond.
7+
#
8+
# https://bugzilla.redhat.com/show_bug.cgi?id=2020773
9+
#
10+
# +---------+
11+
# | fab-br0 |
12+
# +---------+
13+
# |
14+
# +---------+
15+
# | fbond |
16+
# +---------+
17+
# | |
18+
# +------+ +------+
19+
# |veth1 | |veth2 |
20+
# +------+ +------+
21+
#
22+
# We use veths instead of physical interfaces
23+
24+
set -e
25+
tmp=$(mktemp -q dump.XXXXXX)
26+
cleanup() {
27+
ip link del fab-br0 >/dev/null 2>&1 || :
28+
ip link del fbond >/dev/null 2>&1 || :
29+
ip link del veth1-bond >/dev/null 2>&1 || :
30+
ip link del veth2-bond >/dev/null 2>&1 || :
31+
modprobe -r bonding >/dev/null 2>&1 || :
32+
rm -f -- ${tmp}
33+
}
34+
35+
trap cleanup 0 1 2
36+
cleanup
37+
sleep 1
38+
39+
# create the bridge
40+
ip link add fab-br0 address 52:54:00:3B:7C:A6 mtu 1500 type bridge \
41+
forward_delay 15
42+
43+
# create the bond
44+
ip link add fbond type bond mode 4 miimon 200 xmit_hash_policy 1 \
45+
ad_actor_sys_prio 65535 lacp_rate fast
46+
47+
# set bond address
48+
ip link set fbond address 52:54:00:3B:7C:A6
49+
ip link set fbond up
50+
51+
# set again bond sysfs parameters
52+
ip link set fbond type bond ad_actor_sys_prio 65535
53+
54+
# create veths
55+
ip link add name veth1-bond type veth peer name veth1-end
56+
ip link add name veth2-bond type veth peer name veth2-end
57+
58+
# add ports
59+
ip link set fbond master fab-br0
60+
ip link set veth1-bond down master fbond
61+
ip link set veth2-bond down master fbond
62+
63+
# bring up
64+
ip link set veth1-end up
65+
ip link set veth2-end up
66+
ip link set fab-br0 up
67+
ip link set fbond up
68+
ip addr add dev fab-br0 10.0.0.3
69+
70+
tcpdump -n -i veth1-end -e ether proto 0x8809 >${tmp} 2>&1 &
71+
sleep 15
72+
pkill tcpdump >/dev/null 2>&1
73+
rc=0
74+
num=$(grep "packets captured" ${tmp} | awk '{print $1}')
75+
if test "$num" -gt 0; then
76+
echo "PASS, captured ${num}"
77+
else
78+
echo "FAIL"
79+
rc=1
80+
fi
81+
exit $rc
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CONFIG_BONDING=y
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
timeout=60

0 commit comments

Comments
 (0)