|
@@ -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
|