Merge branch 'fix-macvlan-over-alb-bond-support'

Hangbin Liu says:

====================
fix macvlan over alb bond support

Currently, the macvlan over alb bond is broken after commit
14af9963ba ("bonding: Support macvlans on top of tlb/rlb mode bonds").
Fix this and add relate tests.
====================

Link: https://lore.kernel.org/r/20230823071907.3027782-1-liuhangbin@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Paolo Abeni 2023-08-24 10:07:16 +02:00
commit b251610c67
7 changed files with 273 additions and 128 deletions

View file

@ -660,10 +660,10 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
return NULL;
arp = (struct arp_pkt *)skb_network_header(skb);
/* Don't modify or load balance ARPs that do not originate locally
* (e.g.,arrive via a bridge).
/* Don't modify or load balance ARPs that do not originate
* from the bond itself or a VLAN directly above the bond.
*/
if (!bond_slave_has_mac_rx(bond, arp->mac_src))
if (!bond_slave_has_mac_rcu(bond, arp->mac_src))
return NULL;
dev = ip_dev_find(dev_net(bond->dev), arp->ip_src);

View file

@ -722,23 +722,14 @@ static inline struct slave *bond_slave_has_mac(struct bonding *bond,
}
/* Caller must hold rcu_read_lock() for read */
static inline bool bond_slave_has_mac_rx(struct bonding *bond, const u8 *mac)
static inline bool bond_slave_has_mac_rcu(struct bonding *bond, const u8 *mac)
{
struct list_head *iter;
struct slave *tmp;
struct netdev_hw_addr *ha;
bond_for_each_slave_rcu(bond, tmp, iter)
if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
return true;
if (netdev_uc_empty(bond->dev))
return false;
netdev_for_each_uc_addr(ha, bond->dev)
if (ether_addr_equal_64bits(mac, ha->addr))
return true;
return false;
}

View file

@ -9,10 +9,12 @@ TEST_PROGS := \
mode-1-recovery-updelay.sh \
mode-2-recovery-updelay.sh \
bond_options.sh \
bond-eth-type-change.sh
bond-eth-type-change.sh \
bond_macvlan.sh
TEST_FILES := \
lag_lib.sh \
bond_topo_2d1c.sh \
bond_topo_3d1c.sh \
net_forwarding_lib.sh

View file

@ -0,0 +1,99 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Test macvlan over balance-alb
lib_dir=$(dirname "$0")
source ${lib_dir}/bond_topo_2d1c.sh
m1_ns="m1-$(mktemp -u XXXXXX)"
m2_ns="m1-$(mktemp -u XXXXXX)"
m1_ip4="192.0.2.11"
m1_ip6="2001:db8::11"
m2_ip4="192.0.2.12"
m2_ip6="2001:db8::12"
cleanup()
{
ip -n ${m1_ns} link del macv0
ip netns del ${m1_ns}
ip -n ${m2_ns} link del macv0
ip netns del ${m2_ns}
client_destroy
server_destroy
gateway_destroy
}
check_connection()
{
local ns=${1}
local target=${2}
local message=${3:-"macvlan_over_bond"}
RET=0
ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null
check_err $? "ping failed"
log_test "$mode: $message"
}
macvlan_over_bond()
{
local param="$1"
RET=0
# setup new bond mode
bond_reset "${param}"
ip -n ${s_ns} link add link bond0 name macv0 type macvlan mode bridge
ip -n ${s_ns} link set macv0 netns ${m1_ns}
ip -n ${m1_ns} link set dev macv0 up
ip -n ${m1_ns} addr add ${m1_ip4}/24 dev macv0
ip -n ${m1_ns} addr add ${m1_ip6}/24 dev macv0
ip -n ${s_ns} link add link bond0 name macv0 type macvlan mode bridge
ip -n ${s_ns} link set macv0 netns ${m2_ns}
ip -n ${m2_ns} link set dev macv0 up
ip -n ${m2_ns} addr add ${m2_ip4}/24 dev macv0
ip -n ${m2_ns} addr add ${m2_ip6}/24 dev macv0
sleep 2
check_connection "${c_ns}" "${s_ip4}" "IPv4: client->server"
check_connection "${c_ns}" "${s_ip6}" "IPv6: client->server"
check_connection "${c_ns}" "${m1_ip4}" "IPv4: client->macvlan_1"
check_connection "${c_ns}" "${m1_ip6}" "IPv6: client->macvlan_1"
check_connection "${c_ns}" "${m2_ip4}" "IPv4: client->macvlan_2"
check_connection "${c_ns}" "${m2_ip6}" "IPv6: client->macvlan_2"
check_connection "${m1_ns}" "${m2_ip4}" "IPv4: macvlan_1->macvlan_2"
check_connection "${m1_ns}" "${m2_ip6}" "IPv6: macvlan_1->macvlan_2"
sleep 5
check_connection "${s_ns}" "${c_ip4}" "IPv4: server->client"
check_connection "${s_ns}" "${c_ip6}" "IPv6: server->client"
check_connection "${m1_ns}" "${c_ip4}" "IPv4: macvlan_1->client"
check_connection "${m1_ns}" "${c_ip6}" "IPv6: macvlan_1->client"
check_connection "${m2_ns}" "${c_ip4}" "IPv4: macvlan_2->client"
check_connection "${m2_ns}" "${c_ip6}" "IPv6: macvlan_2->client"
check_connection "${m2_ns}" "${m1_ip4}" "IPv4: macvlan_2->macvlan_2"
check_connection "${m2_ns}" "${m1_ip6}" "IPv6: macvlan_2->macvlan_2"
ip -n ${c_ns} neigh flush dev eth0
}
trap cleanup EXIT
setup_prepare
ip netns add ${m1_ns}
ip netns add ${m2_ns}
modes="active-backup balance-tlb balance-alb"
for mode in $modes; do
macvlan_over_bond "mode $mode"
done
exit $EXIT_STATUS

View file

@ -9,10 +9,7 @@ ALL_TESTS="
num_grat_arp
"
REQUIRE_MZ=no
NUM_NETIFS=0
lib_dir=$(dirname "$0")
source ${lib_dir}/net_forwarding_lib.sh
source ${lib_dir}/bond_topo_3d1c.sh
skip_prio()

View file

@ -0,0 +1,158 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Topology for Bond mode 1,5,6 testing
#
# +-------------------------+
# | bond0 | Server
# | + | 192.0.2.1/24
# | eth0 | eth1 | 2001:db8::1/24
# | +---+---+ |
# | | | |
# +-------------------------+
# | |
# +-------------------------+
# | | | |
# | +---+-------+---+ | Gateway
# | | br0 | | 192.0.2.254/24
# | +-------+-------+ | 2001:db8::254/24
# | | |
# +-------------------------+
# |
# +-------------------------+
# | | | Client
# | + | 192.0.2.10/24
# | eth0 | 2001:db8::10/24
# +-------------------------+
REQUIRE_MZ=no
NUM_NETIFS=0
lib_dir=$(dirname "$0")
source ${lib_dir}/net_forwarding_lib.sh
s_ns="s-$(mktemp -u XXXXXX)"
c_ns="c-$(mktemp -u XXXXXX)"
g_ns="g-$(mktemp -u XXXXXX)"
s_ip4="192.0.2.1"
c_ip4="192.0.2.10"
g_ip4="192.0.2.254"
s_ip6="2001:db8::1"
c_ip6="2001:db8::10"
g_ip6="2001:db8::254"
gateway_create()
{
ip netns add ${g_ns}
ip -n ${g_ns} link add br0 type bridge
ip -n ${g_ns} link set br0 up
ip -n ${g_ns} addr add ${g_ip4}/24 dev br0
ip -n ${g_ns} addr add ${g_ip6}/24 dev br0
}
gateway_destroy()
{
ip -n ${g_ns} link del br0
ip netns del ${g_ns}
}
server_create()
{
ip netns add ${s_ns}
ip -n ${s_ns} link add bond0 type bond mode active-backup miimon 100
for i in $(seq 0 1); do
ip -n ${s_ns} link add eth${i} type veth peer name s${i} netns ${g_ns}
ip -n ${g_ns} link set s${i} up
ip -n ${g_ns} link set s${i} master br0
ip -n ${s_ns} link set eth${i} master bond0
tc -n ${g_ns} qdisc add dev s${i} clsact
done
ip -n ${s_ns} link set bond0 up
ip -n ${s_ns} addr add ${s_ip4}/24 dev bond0
ip -n ${s_ns} addr add ${s_ip6}/24 dev bond0
sleep 2
}
# Reset bond with new mode and options
bond_reset()
{
# Count the eth link number in real-time as this function
# maybe called from other topologies.
local link_num=$(ip -n ${s_ns} -br link show | grep -c "^eth")
local param="$1"
link_num=$((link_num -1))
ip -n ${s_ns} link set bond0 down
ip -n ${s_ns} link del bond0
ip -n ${s_ns} link add bond0 type bond $param
for i in $(seq 0 ${link_num}); do
ip -n ${s_ns} link set eth$i master bond0
done
ip -n ${s_ns} link set bond0 up
ip -n ${s_ns} addr add ${s_ip4}/24 dev bond0
ip -n ${s_ns} addr add ${s_ip6}/24 dev bond0
sleep 2
}
server_destroy()
{
# Count the eth link number in real-time as this function
# maybe called from other topologies.
local link_num=$(ip -n ${s_ns} -br link show | grep -c "^eth")
link_num=$((link_num -1))
for i in $(seq 0 ${link_num}); do
ip -n ${s_ns} link del eth${i}
done
ip netns del ${s_ns}
}
client_create()
{
ip netns add ${c_ns}
ip -n ${c_ns} link add eth0 type veth peer name c0 netns ${g_ns}
ip -n ${g_ns} link set c0 up
ip -n ${g_ns} link set c0 master br0
ip -n ${c_ns} link set eth0 up
ip -n ${c_ns} addr add ${c_ip4}/24 dev eth0
ip -n ${c_ns} addr add ${c_ip6}/24 dev eth0
}
client_destroy()
{
ip -n ${c_ns} link del eth0
ip netns del ${c_ns}
}
setup_prepare()
{
gateway_create
server_create
client_create
}
cleanup()
{
pre_cleanup
client_destroy
server_destroy
gateway_destroy
}
bond_check_connection()
{
local msg=${1:-"check connection"}
sleep 2
ip netns exec ${s_ns} ping ${c_ip4} -c5 -i 0.1 &>/dev/null
check_err $? "${msg}: ping failed"
ip netns exec ${s_ns} ping6 ${c_ip6} -c5 -i 0.1 &>/dev/null
check_err $? "${msg}: ping6 failed"
}

View file

@ -25,121 +25,19 @@
# | eth0 | 2001:db8::10/24
# +-------------------------------------+
s_ns="s-$(mktemp -u XXXXXX)"
c_ns="c-$(mktemp -u XXXXXX)"
g_ns="g-$(mktemp -u XXXXXX)"
s_ip4="192.0.2.1"
c_ip4="192.0.2.10"
g_ip4="192.0.2.254"
s_ip6="2001:db8::1"
c_ip6="2001:db8::10"
g_ip6="2001:db8::254"
gateway_create()
{
ip netns add ${g_ns}
ip -n ${g_ns} link add br0 type bridge
ip -n ${g_ns} link set br0 up
ip -n ${g_ns} addr add ${g_ip4}/24 dev br0
ip -n ${g_ns} addr add ${g_ip6}/24 dev br0
}
gateway_destroy()
{
ip -n ${g_ns} link del br0
ip netns del ${g_ns}
}
server_create()
{
ip netns add ${s_ns}
ip -n ${s_ns} link add bond0 type bond mode active-backup miimon 100
for i in $(seq 0 2); do
ip -n ${s_ns} link add eth${i} type veth peer name s${i} netns ${g_ns}
ip -n ${g_ns} link set s${i} up
ip -n ${g_ns} link set s${i} master br0
ip -n ${s_ns} link set eth${i} master bond0
tc -n ${g_ns} qdisc add dev s${i} clsact
done
ip -n ${s_ns} link set bond0 up
ip -n ${s_ns} addr add ${s_ip4}/24 dev bond0
ip -n ${s_ns} addr add ${s_ip6}/24 dev bond0
sleep 2
}
# Reset bond with new mode and options
bond_reset()
{
local param="$1"
ip -n ${s_ns} link set bond0 down
ip -n ${s_ns} link del bond0
ip -n ${s_ns} link add bond0 type bond $param
for i in $(seq 0 2); do
ip -n ${s_ns} link set eth$i master bond0
done
ip -n ${s_ns} link set bond0 up
ip -n ${s_ns} addr add ${s_ip4}/24 dev bond0
ip -n ${s_ns} addr add ${s_ip6}/24 dev bond0
sleep 2
}
server_destroy()
{
for i in $(seq 0 2); do
ip -n ${s_ns} link del eth${i}
done
ip netns del ${s_ns}
}
client_create()
{
ip netns add ${c_ns}
ip -n ${c_ns} link add eth0 type veth peer name c0 netns ${g_ns}
ip -n ${g_ns} link set c0 up
ip -n ${g_ns} link set c0 master br0
ip -n ${c_ns} link set eth0 up
ip -n ${c_ns} addr add ${c_ip4}/24 dev eth0
ip -n ${c_ns} addr add ${c_ip6}/24 dev eth0
}
client_destroy()
{
ip -n ${c_ns} link del eth0
ip netns del ${c_ns}
}
source bond_topo_2d1c.sh
setup_prepare()
{
gateway_create
server_create
client_create
}
cleanup()
{
pre_cleanup
client_destroy
server_destroy
gateway_destroy
}
bond_check_connection()
{
local msg=${1:-"check connection"}
sleep 2
ip netns exec ${s_ns} ping ${c_ip4} -c5 -i 0.1 &>/dev/null
check_err $? "${msg}: ping failed"
ip netns exec ${s_ns} ping6 ${c_ip6} -c5 -i 0.1 &>/dev/null
check_err $? "${msg}: ping6 failed"
# Add the extra device as we use 3 down links for bond0
local i=2
ip -n ${s_ns} link add eth${i} type veth peer name s${i} netns ${g_ns}
ip -n ${g_ns} link set s${i} up
ip -n ${g_ns} link set s${i} master br0
ip -n ${s_ns} link set eth${i} master bond0
tc -n ${g_ns} qdisc add dev s${i} clsact
}