Commit 1d63f0e3 authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-Various-fixes'

Ido Schimmel says:

====================
mlxsw: Various fixes

This patchset contains various fixes for mlxsw.

Patch #1 fixes an hash polarization problem when a nexthop device is a
LAG device. This is caused by the fact that the same seed is used for
the LAG and ECMP hash functions.

Patch #2 fixes an issue in which the driver fails to refresh a nexthop
neighbour after it becomes dead. This prevents the nexthop from ever
being written to the adjacency table and used to forward traffic. Patch

Patch #4 fixes a wrong extraction of TOS value in flower offload code.
Patch #5 is a test case.

Patch #6 works around a buffer issue in Spectrum-2 by reducing the
default sizes of the shared buffer pools.

Patch #7 prevents prio-tagged packets from entering the switch when PVID
is removed from the bridge port.

Please consider patches #2, #4 and #6 for 5.1.y
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 648ee6ce 4b14cc31
......@@ -997,7 +997,7 @@ static inline void mlxsw_reg_spaft_pack(char *payload, u8 local_port,
MLXSW_REG_ZERO(spaft, payload);
mlxsw_reg_spaft_local_port_set(payload, local_port);
mlxsw_reg_spaft_allow_untagged_set(payload, allow_untagged);
mlxsw_reg_spaft_allow_prio_tagged_set(payload, true);
mlxsw_reg_spaft_allow_prio_tagged_set(payload, allow_untagged);
mlxsw_reg_spaft_allow_tagged_set(payload, true);
}
......
......@@ -4280,13 +4280,16 @@ static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
}
}
#define MLXSW_SP_LAG_SEED_INIT 0xcafecafe
static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
{
char slcr_pl[MLXSW_REG_SLCR_LEN];
u32 seed;
int err;
seed = jhash(mlxsw_sp->base_mac, sizeof(mlxsw_sp->base_mac), 0);
seed = jhash(mlxsw_sp->base_mac, sizeof(mlxsw_sp->base_mac),
MLXSW_SP_LAG_SEED_INIT);
mlxsw_reg_slcr_pack(slcr_pl, MLXSW_REG_SLCR_LAG_HASH_SMAC |
MLXSW_REG_SLCR_LAG_HASH_DMAC |
MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE |
......
......@@ -437,8 +437,8 @@ static const struct mlxsw_sp_sb_pr mlxsw_sp1_sb_prs[] = {
MLXSW_SP1_SB_PR_CPU_SIZE, true, false),
};
#define MLXSW_SP2_SB_PR_INGRESS_SIZE 40960000
#define MLXSW_SP2_SB_PR_EGRESS_SIZE 40960000
#define MLXSW_SP2_SB_PR_INGRESS_SIZE 38128752
#define MLXSW_SP2_SB_PR_EGRESS_SIZE 38128752
#define MLXSW_SP2_SB_PR_CPU_SIZE (256 * 1000)
/* Order according to mlxsw_sp2_sb_pool_dess */
......
......@@ -247,8 +247,8 @@ static int mlxsw_sp_flower_parse_ip(struct mlxsw_sp *mlxsw_sp,
match.mask->tos & 0x3);
mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_IP_DSCP,
match.key->tos >> 6,
match.mask->tos >> 6);
match.key->tos >> 2,
match.mask->tos >> 2);
return 0;
}
......
......@@ -2363,7 +2363,7 @@ static void mlxsw_sp_router_probe_unresolved_nexthops(struct work_struct *work)
static void
mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry,
bool removing);
bool removing, bool dead);
static enum mlxsw_reg_rauht_op mlxsw_sp_rauht_op(bool adding)
{
......@@ -2507,7 +2507,8 @@ static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
memcpy(neigh_entry->ha, ha, ETH_ALEN);
mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, entry_connected);
mlxsw_sp_nexthop_neigh_update(mlxsw_sp, neigh_entry, !entry_connected);
mlxsw_sp_nexthop_neigh_update(mlxsw_sp, neigh_entry, !entry_connected,
dead);
if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
......@@ -3472,13 +3473,79 @@ static void __mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp_nexthop *nh,
nh->update = 1;
}
static int
mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry)
{
struct neighbour *n, *old_n = neigh_entry->key.n;
struct mlxsw_sp_nexthop *nh;
bool entry_connected;
u8 nud_state, dead;
int err;
nh = list_first_entry(&neigh_entry->nexthop_list,
struct mlxsw_sp_nexthop, neigh_list_node);
n = neigh_lookup(nh->nh_grp->neigh_tbl, &nh->gw_addr, nh->rif->dev);
if (!n) {
n = neigh_create(nh->nh_grp->neigh_tbl, &nh->gw_addr,
nh->rif->dev);
if (IS_ERR(n))
return PTR_ERR(n);
neigh_event_send(n, NULL);
}
mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry);
neigh_entry->key.n = n;
err = mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry);
if (err)
goto err_neigh_entry_insert;
read_lock_bh(&n->lock);
nud_state = n->nud_state;
dead = n->dead;
read_unlock_bh(&n->lock);
entry_connected = nud_state & NUD_VALID && !dead;
list_for_each_entry(nh, &neigh_entry->nexthop_list,
neigh_list_node) {
neigh_release(old_n);
neigh_clone(n);
__mlxsw_sp_nexthop_neigh_update(nh, !entry_connected);
mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
}
neigh_release(n);
return 0;
err_neigh_entry_insert:
neigh_entry->key.n = old_n;
mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry);
neigh_release(n);
return err;
}
static void
mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry,
bool removing)
bool removing, bool dead)
{
struct mlxsw_sp_nexthop *nh;
if (list_empty(&neigh_entry->nexthop_list))
return;
if (dead) {
int err;
err = mlxsw_sp_nexthop_dead_neigh_replace(mlxsw_sp,
neigh_entry);
if (err)
dev_err(mlxsw_sp->bus_info->dev, "Failed to replace dead neigh\n");
return;
}
list_for_each_entry(nh, &neigh_entry->nexthop_list,
neigh_list_node) {
__mlxsw_sp_nexthop_neigh_update(nh, removing);
......
......@@ -28,6 +28,7 @@ ALL_TESTS="
vlan_interface_uppers_test
bridge_extern_learn_test
neigh_offload_test
nexthop_offload_test
devlink_reload_test
"
NUM_NETIFS=2
......@@ -607,6 +608,52 @@ neigh_offload_test()
ip -4 address del 192.0.2.1/24 dev $swp1
}
nexthop_offload_test()
{
# Test that IPv4 and IPv6 nexthops are marked as offloaded
RET=0
sysctl_set net.ipv6.conf.$swp2.keep_addr_on_down 1
simple_if_init $swp1 192.0.2.1/24 2001:db8:1::1/64
simple_if_init $swp2 192.0.2.2/24 2001:db8:1::2/64
setup_wait
ip -4 route add 198.51.100.0/24 vrf v$swp1 \
nexthop via 192.0.2.2 dev $swp1
ip -6 route add 2001:db8:2::/64 vrf v$swp1 \
nexthop via 2001:db8:1::2 dev $swp1
ip -4 route show 198.51.100.0/24 vrf v$swp1 | grep -q offload
check_err $? "ipv4 nexthop not marked as offloaded when should"
ip -6 route show 2001:db8:2::/64 vrf v$swp1 | grep -q offload
check_err $? "ipv6 nexthop not marked as offloaded when should"
ip link set dev $swp2 down
sleep 1
ip -4 route show 198.51.100.0/24 vrf v$swp1 | grep -q offload
check_fail $? "ipv4 nexthop marked as offloaded when should not"
ip -6 route show 2001:db8:2::/64 vrf v$swp1 | grep -q offload
check_fail $? "ipv6 nexthop marked as offloaded when should not"
ip link set dev $swp2 up
setup_wait
ip -4 route show 198.51.100.0/24 vrf v$swp1 | grep -q offload
check_err $? "ipv4 nexthop not marked as offloaded after neigh add"
ip -6 route show 2001:db8:2::/64 vrf v$swp1 | grep -q offload
check_err $? "ipv6 nexthop not marked as offloaded after neigh add"
log_test "nexthop offload indication"
ip -6 route del 2001:db8:2::/64 vrf v$swp1
ip -4 route del 198.51.100.0/24 vrf v$swp1
simple_if_fini $swp2 192.0.2.2/24 2001:db8:1::2/64
simple_if_fini $swp1 192.0.2.1/24 2001:db8:1::1/64
sysctl_restore net.ipv6.conf.$swp2.keep_addr_on_down
}
devlink_reload_test()
{
# Test that after executing all the above configuration tests, a
......
......@@ -2,7 +2,8 @@
# SPDX-License-Identifier: GPL-2.0
ALL_TESTS="match_dst_mac_test match_src_mac_test match_dst_ip_test \
match_src_ip_test match_ip_flags_test match_pcp_test match_vlan_test"
match_src_ip_test match_ip_flags_test match_pcp_test match_vlan_test \
match_ip_tos_test"
NUM_NETIFS=2
source tc_common.sh
source lib.sh
......@@ -276,6 +277,39 @@ match_vlan_test()
log_test "VLAN match ($tcflags)"
}
match_ip_tos_test()
{
RET=0
tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \
$tcflags dst_ip 192.0.2.2 ip_tos 0x20 action drop
tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \
$tcflags dst_ip 192.0.2.2 ip_tos 0x18 action drop
$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
-t ip tos=18 -q
tc_check_packets "dev $h2 ingress" 101 1
check_fail $? "Matched on a wrong filter (0x18)"
tc_check_packets "dev $h2 ingress" 102 1
check_err $? "Did not match on correct filter (0x18)"
$MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \
-t ip tos=20 -q
tc_check_packets "dev $h2 ingress" 102 2
check_fail $? "Matched on a wrong filter (0x20)"
tc_check_packets "dev $h2 ingress" 101 1
check_err $? "Did not match on correct filter (0x20)"
tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
log_test "ip_tos match ($tcflags)"
}
setup_prepare()
{
h1=${NETIFS[p1]}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment