Merge branch 'mlxsw-Add-neighbour-offload-indication'

Ido Schimmel says:

====================
mlxsw: Add neighbour offload indication

Neighbour entries are programmed to the device's table so that the
correct destination MAC will be specified in a packet after it was
routed.

Despite being programmed to the device and unlike routes and FDB
entries, neighbour entries are currently not marked as offloaded. This
patchset changes that.

Patch #1 is a preparatory patch to make sure we only mark a neighbour as
offloaded in case it was successfully programmed to the device.

Patch #2 sets the offload indication on neighbours.

Patch #3 adds a test to verify above mentioned functionality.

Patched iproute2 version that prints the offload indication is available
here [1].

[1] https://github.com/idosch/iproute2/tree/idosch-next
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2019-04-15 13:29:21 -07:00
commit 93144b0ecd
2 changed files with 47 additions and 8 deletions

View File

@ -2371,7 +2371,7 @@ static enum mlxsw_reg_rauht_op mlxsw_sp_rauht_op(bool adding)
MLXSW_REG_RAUHT_OP_WRITE_DELETE; MLXSW_REG_RAUHT_OP_WRITE_DELETE;
} }
static void static int
mlxsw_sp_router_neigh_entry_op4(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_router_neigh_entry_op4(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry, struct mlxsw_sp_neigh_entry *neigh_entry,
enum mlxsw_reg_rauht_op op) enum mlxsw_reg_rauht_op op)
@ -2385,10 +2385,10 @@ mlxsw_sp_router_neigh_entry_op4(struct mlxsw_sp *mlxsw_sp,
if (neigh_entry->counter_valid) if (neigh_entry->counter_valid)
mlxsw_reg_rauht_pack_counter(rauht_pl, mlxsw_reg_rauht_pack_counter(rauht_pl,
neigh_entry->counter_index); neigh_entry->counter_index);
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl);
} }
static void static int
mlxsw_sp_router_neigh_entry_op6(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_router_neigh_entry_op6(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry, struct mlxsw_sp_neigh_entry *neigh_entry,
enum mlxsw_reg_rauht_op op) enum mlxsw_reg_rauht_op op)
@ -2402,7 +2402,7 @@ mlxsw_sp_router_neigh_entry_op6(struct mlxsw_sp *mlxsw_sp,
if (neigh_entry->counter_valid) if (neigh_entry->counter_valid)
mlxsw_reg_rauht_pack_counter(rauht_pl, mlxsw_reg_rauht_pack_counter(rauht_pl,
neigh_entry->counter_index); neigh_entry->counter_index);
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl);
} }
bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry) bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry)
@ -2424,20 +2424,33 @@ mlxsw_sp_neigh_entry_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry, struct mlxsw_sp_neigh_entry *neigh_entry,
bool adding) bool adding)
{ {
enum mlxsw_reg_rauht_op op = mlxsw_sp_rauht_op(adding);
int err;
if (!adding && !neigh_entry->connected) if (!adding && !neigh_entry->connected)
return; return;
neigh_entry->connected = adding; neigh_entry->connected = adding;
if (neigh_entry->key.n->tbl->family == AF_INET) { if (neigh_entry->key.n->tbl->family == AF_INET) {
mlxsw_sp_router_neigh_entry_op4(mlxsw_sp, neigh_entry, err = mlxsw_sp_router_neigh_entry_op4(mlxsw_sp, neigh_entry,
mlxsw_sp_rauht_op(adding)); op);
if (err)
return;
} else if (neigh_entry->key.n->tbl->family == AF_INET6) { } else if (neigh_entry->key.n->tbl->family == AF_INET6) {
if (mlxsw_sp_neigh_ipv6_ignore(neigh_entry)) if (mlxsw_sp_neigh_ipv6_ignore(neigh_entry))
return; return;
mlxsw_sp_router_neigh_entry_op6(mlxsw_sp, neigh_entry, err = mlxsw_sp_router_neigh_entry_op6(mlxsw_sp, neigh_entry,
mlxsw_sp_rauht_op(adding)); op);
if (err)
return;
} else { } else {
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
return;
} }
if (adding)
neigh_entry->key.n->flags |= NTF_OFFLOADED;
else
neigh_entry->key.n->flags &= ~NTF_OFFLOADED;
} }
void void

View File

@ -26,6 +26,7 @@ ALL_TESTS="
lag_dev_deletion_test lag_dev_deletion_test
vlan_interface_uppers_test vlan_interface_uppers_test
bridge_extern_learn_test bridge_extern_learn_test
neigh_offload_test
devlink_reload_test devlink_reload_test
" "
NUM_NETIFS=2 NUM_NETIFS=2
@ -561,6 +562,31 @@ bridge_extern_learn_test()
ip link del dev br0 ip link del dev br0
} }
neigh_offload_test()
{
# Test that IPv4 and IPv6 neighbour entries are marked as offloaded
RET=0
ip -4 address add 192.0.2.1/24 dev $swp1
ip -6 address add 2001:db8:1::1/64 dev $swp1
ip -4 neigh add 192.0.2.2 lladdr de:ad:be:ef:13:37 nud perm dev $swp1
ip -6 neigh add 2001:db8:1::2 lladdr de:ad:be:ef:13:37 nud perm \
dev $swp1
ip -4 neigh show dev $swp1 | grep 192.0.2.2 | grep -q offload
check_err $? "ipv4 neigh entry not marked as offloaded when should"
ip -6 neigh show dev $swp1 | grep 2001:db8:1::2 | grep -q offload
check_err $? "ipv6 neigh entry not marked as offloaded when should"
log_test "neighbour offload indication"
ip -6 neigh del 2001:db8:1::2 dev $swp1
ip -4 neigh del 192.0.2.2 dev $swp1
ip -6 address del 2001:db8:1::1/64 dev $swp1
ip -4 address del 192.0.2.1/24 dev $swp1
}
devlink_reload_test() devlink_reload_test()
{ {
# Test that after executing all the above configuration tests, a # Test that after executing all the above configuration tests, a