aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c42
1 files changed, 13 insertions, 29 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index c452bd3440a0..136a50cffa85 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1623,7 +1623,7 @@ mlxsw_sp_fib_entry_should_offload(const struct mlxsw_sp_fib_entry *fib_entry)
case MLXSW_SP_FIB_ENTRY_TYPE_REMOTE:
return !!nh_group->adj_index_valid;
case MLXSW_SP_FIB_ENTRY_TYPE_LOCAL:
- return true;
+ return !!nh_group->nh_rif;
default:
return false;
}
@@ -1718,16 +1718,25 @@ static int mlxsw_sp_fib_entry_op4_local(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_reg_ralue_op op)
{
struct mlxsw_sp_rif *r = fib_entry->nh_group->nh_rif;
+ enum mlxsw_reg_ralue_trap_action trap_action;
char ralue_pl[MLXSW_REG_RALUE_LEN];
u32 *p_dip = (u32 *) fib_entry->key.addr;
struct mlxsw_sp_vr *vr = fib_entry->vr;
+ u16 trap_id = 0;
+ u16 rif = 0;
+
+ if (mlxsw_sp_fib_entry_should_offload(fib_entry)) {
+ trap_action = MLXSW_REG_RALUE_TRAP_ACTION_NOP;
+ rif = r->rif;
+ } else {
+ trap_action = MLXSW_REG_RALUE_TRAP_ACTION_TRAP;
+ trap_id = MLXSW_TRAP_ID_RTR_INGRESS0;
+ }
mlxsw_reg_ralue_pack4(ralue_pl,
(enum mlxsw_reg_ralxx_protocol) vr->proto, op,
vr->id, fib_entry->key.prefix_len, *p_dip);
- mlxsw_reg_ralue_act_local_pack(ralue_pl,
- MLXSW_REG_RALUE_TRAP_ACTION_NOP, 0,
- r->rif);
+ mlxsw_reg_ralue_act_local_pack(ralue_pl, trap_action, trap_id, rif);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
}
@@ -1798,8 +1807,6 @@ mlxsw_sp_fib4_entry_type_set(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry)
{
struct fib_info *fi = fen_info->fi;
- struct mlxsw_sp_rif *r = NULL;
- int nhsel;
if (fen_info->type == RTN_LOCAL || fen_info->type == RTN_BROADCAST) {
fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
@@ -1807,29 +1814,6 @@ mlxsw_sp_fib4_entry_type_set(struct mlxsw_sp *mlxsw_sp,
}
if (fen_info->type != RTN_UNICAST)
return -EINVAL;
-
- for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) {
- const struct fib_nh *nh = &fi->fib_nh[nhsel];
-
- if (!nh->nh_dev)
- continue;
- r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, nh->nh_dev);
- if (!r) {
- /* In case router interface is not found for
- * at least one of the nexthops, that means
- * the nexthop points to some device unrelated
- * to us. Set trap and pass the packets for
- * this prefix to kernel.
- */
- break;
- }
- }
-
- if (!r) {
- fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
- return 0;
- }
-
if (fi->fib_nh->nh_scope != RT_SCOPE_LINK)
fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
else