@@ -4096,131 +4096,128 @@ mlxsw_sp_rt6_nexthop(struct mlxsw_sp_nexthop_group *nh_grp,
40964096}
40974097
40984098static void
4099- mlxsw_sp_fib4_entry_offload_set (struct mlxsw_sp_fib_entry * fib_entry )
4099+ mlxsw_sp_fib4_entry_hw_flags_set (struct mlxsw_sp * mlxsw_sp ,
4100+ struct mlxsw_sp_fib_entry * fib_entry )
41004101{
4101- struct mlxsw_sp_nexthop_group * nh_grp = fib_entry -> nh_group ;
4102- int i ;
4103-
4104- if (fib_entry -> type == MLXSW_SP_FIB_ENTRY_TYPE_LOCAL ||
4105- fib_entry -> type == MLXSW_SP_FIB_ENTRY_TYPE_BLACKHOLE ||
4106- fib_entry -> type == MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP ||
4107- fib_entry -> type == MLXSW_SP_FIB_ENTRY_TYPE_NVE_DECAP ) {
4108- nh_grp -> nexthops -> key .fib_nh -> fib_nh_flags |= RTNH_F_OFFLOAD ;
4109- return ;
4110- }
4111-
4112- for (i = 0 ; i < nh_grp -> count ; i ++ ) {
4113- struct mlxsw_sp_nexthop * nh = & nh_grp -> nexthops [i ];
4102+ struct fib_info * fi = mlxsw_sp_nexthop4_group_fi (fib_entry -> nh_group );
4103+ u32 * p_dst = (u32 * ) fib_entry -> fib_node -> key .addr ;
4104+ int dst_len = fib_entry -> fib_node -> key .prefix_len ;
4105+ struct mlxsw_sp_fib4_entry * fib4_entry ;
4106+ struct fib_rt_info fri ;
4107+ bool should_offload ;
41144108
4115- if (nh -> offloaded )
4116- nh -> key .fib_nh -> fib_nh_flags |= RTNH_F_OFFLOAD ;
4117- else
4118- nh -> key .fib_nh -> fib_nh_flags &= ~RTNH_F_OFFLOAD ;
4119- }
4109+ should_offload = mlxsw_sp_fib_entry_should_offload (fib_entry );
4110+ fib4_entry = container_of (fib_entry , struct mlxsw_sp_fib4_entry ,
4111+ common );
4112+ fri .fi = fi ;
4113+ fri .tb_id = fib4_entry -> tb_id ;
4114+ fri .dst = cpu_to_be32 (* p_dst );
4115+ fri .dst_len = dst_len ;
4116+ fri .tos = fib4_entry -> tos ;
4117+ fri .type = fib4_entry -> type ;
4118+ fri .offload = should_offload ;
4119+ fri .trap = !should_offload ;
4120+ fib_alias_hw_flags_set (mlxsw_sp_net (mlxsw_sp ), & fri );
41204121}
41214122
41224123static void
4123- mlxsw_sp_fib4_entry_offload_unset (struct mlxsw_sp_fib_entry * fib_entry )
4124+ mlxsw_sp_fib4_entry_hw_flags_clear (struct mlxsw_sp * mlxsw_sp ,
4125+ struct mlxsw_sp_fib_entry * fib_entry )
41244126{
4125- struct mlxsw_sp_nexthop_group * nh_grp = fib_entry -> nh_group ;
4126- int i ;
4127-
4128- if (!list_is_singular (& nh_grp -> fib_list ))
4129- return ;
4130-
4131- for (i = 0 ; i < nh_grp -> count ; i ++ ) {
4132- struct mlxsw_sp_nexthop * nh = & nh_grp -> nexthops [i ];
4127+ struct fib_info * fi = mlxsw_sp_nexthop4_group_fi (fib_entry -> nh_group );
4128+ u32 * p_dst = (u32 * ) fib_entry -> fib_node -> key .addr ;
4129+ int dst_len = fib_entry -> fib_node -> key .prefix_len ;
4130+ struct mlxsw_sp_fib4_entry * fib4_entry ;
4131+ struct fib_rt_info fri ;
41334132
4134- nh -> key .fib_nh -> fib_nh_flags &= ~RTNH_F_OFFLOAD ;
4135- }
4133+ fib4_entry = container_of (fib_entry , struct mlxsw_sp_fib4_entry ,
4134+ common );
4135+ fri .fi = fi ;
4136+ fri .tb_id = fib4_entry -> tb_id ;
4137+ fri .dst = cpu_to_be32 (* p_dst );
4138+ fri .dst_len = dst_len ;
4139+ fri .tos = fib4_entry -> tos ;
4140+ fri .type = fib4_entry -> type ;
4141+ fri .offload = false;
4142+ fri .trap = false;
4143+ fib_alias_hw_flags_set (mlxsw_sp_net (mlxsw_sp ), & fri );
41364144}
41374145
41384146static void
4139- mlxsw_sp_fib6_entry_offload_set (struct mlxsw_sp_fib_entry * fib_entry )
4147+ mlxsw_sp_fib6_entry_hw_flags_set (struct mlxsw_sp * mlxsw_sp ,
4148+ struct mlxsw_sp_fib_entry * fib_entry )
41404149{
41414150 struct mlxsw_sp_fib6_entry * fib6_entry ;
41424151 struct mlxsw_sp_rt6 * mlxsw_sp_rt6 ;
4152+ bool should_offload ;
4153+
4154+ should_offload = mlxsw_sp_fib_entry_should_offload (fib_entry );
41434155
4156+ /* In IPv6 a multipath route is represented using multiple routes, so
4157+ * we need to set the flags on all of them.
4158+ */
41444159 fib6_entry = container_of (fib_entry , struct mlxsw_sp_fib6_entry ,
41454160 common );
4146-
4147- if (fib_entry -> type == MLXSW_SP_FIB_ENTRY_TYPE_LOCAL ||
4148- fib_entry -> type == MLXSW_SP_FIB_ENTRY_TYPE_BLACKHOLE ) {
4149- list_first_entry (& fib6_entry -> rt6_list , struct mlxsw_sp_rt6 ,
4150- list )-> rt -> fib6_nh -> fib_nh_flags |= RTNH_F_OFFLOAD ;
4151- return ;
4152- }
4153-
4154- list_for_each_entry (mlxsw_sp_rt6 , & fib6_entry -> rt6_list , list ) {
4155- struct mlxsw_sp_nexthop_group * nh_grp = fib_entry -> nh_group ;
4156- struct fib6_nh * fib6_nh = mlxsw_sp_rt6 -> rt -> fib6_nh ;
4157- struct mlxsw_sp_nexthop * nh ;
4158-
4159- nh = mlxsw_sp_rt6_nexthop (nh_grp , mlxsw_sp_rt6 );
4160- if (nh && nh -> offloaded )
4161- fib6_nh -> fib_nh_flags |= RTNH_F_OFFLOAD ;
4162- else
4163- fib6_nh -> fib_nh_flags &= ~RTNH_F_OFFLOAD ;
4164- }
4161+ list_for_each_entry (mlxsw_sp_rt6 , & fib6_entry -> rt6_list , list )
4162+ fib6_info_hw_flags_set (mlxsw_sp_rt6 -> rt , should_offload ,
4163+ !should_offload );
41654164}
41664165
41674166static void
4168- mlxsw_sp_fib6_entry_offload_unset (struct mlxsw_sp_fib_entry * fib_entry )
4167+ mlxsw_sp_fib6_entry_hw_flags_clear (struct mlxsw_sp * mlxsw_sp ,
4168+ struct mlxsw_sp_fib_entry * fib_entry )
41694169{
41704170 struct mlxsw_sp_fib6_entry * fib6_entry ;
41714171 struct mlxsw_sp_rt6 * mlxsw_sp_rt6 ;
41724172
41734173 fib6_entry = container_of (fib_entry , struct mlxsw_sp_fib6_entry ,
41744174 common );
4175- list_for_each_entry (mlxsw_sp_rt6 , & fib6_entry -> rt6_list , list ) {
4176- struct fib6_info * rt = mlxsw_sp_rt6 -> rt ;
4177-
4178- rt -> fib6_nh -> fib_nh_flags &= ~RTNH_F_OFFLOAD ;
4179- }
4175+ list_for_each_entry (mlxsw_sp_rt6 , & fib6_entry -> rt6_list , list )
4176+ fib6_info_hw_flags_set (mlxsw_sp_rt6 -> rt , false, false);
41804177}
41814178
4182- static void mlxsw_sp_fib_entry_offload_set (struct mlxsw_sp_fib_entry * fib_entry )
4179+ static void
4180+ mlxsw_sp_fib_entry_hw_flags_set (struct mlxsw_sp * mlxsw_sp ,
4181+ struct mlxsw_sp_fib_entry * fib_entry )
41834182{
41844183 switch (fib_entry -> fib_node -> fib -> proto ) {
41854184 case MLXSW_SP_L3_PROTO_IPV4 :
4186- mlxsw_sp_fib4_entry_offload_set ( fib_entry );
4185+ mlxsw_sp_fib4_entry_hw_flags_set ( mlxsw_sp , fib_entry );
41874186 break ;
41884187 case MLXSW_SP_L3_PROTO_IPV6 :
4189- mlxsw_sp_fib6_entry_offload_set ( fib_entry );
4188+ mlxsw_sp_fib6_entry_hw_flags_set ( mlxsw_sp , fib_entry );
41904189 break ;
41914190 }
41924191}
41934192
41944193static void
4195- mlxsw_sp_fib_entry_offload_unset (struct mlxsw_sp_fib_entry * fib_entry )
4194+ mlxsw_sp_fib_entry_hw_flags_clear (struct mlxsw_sp * mlxsw_sp ,
4195+ struct mlxsw_sp_fib_entry * fib_entry )
41964196{
41974197 switch (fib_entry -> fib_node -> fib -> proto ) {
41984198 case MLXSW_SP_L3_PROTO_IPV4 :
4199- mlxsw_sp_fib4_entry_offload_unset ( fib_entry );
4199+ mlxsw_sp_fib4_entry_hw_flags_clear ( mlxsw_sp , fib_entry );
42004200 break ;
42014201 case MLXSW_SP_L3_PROTO_IPV6 :
4202- mlxsw_sp_fib6_entry_offload_unset ( fib_entry );
4202+ mlxsw_sp_fib6_entry_hw_flags_clear ( mlxsw_sp , fib_entry );
42034203 break ;
42044204 }
42054205}
42064206
42074207static void
4208- mlxsw_sp_fib_entry_offload_refresh (struct mlxsw_sp_fib_entry * fib_entry ,
4209- enum mlxsw_reg_ralue_op op , int err )
4208+ mlxsw_sp_fib_entry_hw_flags_refresh (struct mlxsw_sp * mlxsw_sp ,
4209+ struct mlxsw_sp_fib_entry * fib_entry ,
4210+ enum mlxsw_reg_ralue_op op )
42104211{
42114212 switch (op ) {
4212- case MLXSW_REG_RALUE_OP_WRITE_DELETE :
4213- return mlxsw_sp_fib_entry_offload_unset (fib_entry );
42144213 case MLXSW_REG_RALUE_OP_WRITE_WRITE :
4215- if (err )
4216- return ;
4217- if (mlxsw_sp_fib_entry_should_offload (fib_entry ))
4218- mlxsw_sp_fib_entry_offload_set (fib_entry );
4219- else
4220- mlxsw_sp_fib_entry_offload_unset (fib_entry );
4221- return ;
4214+ mlxsw_sp_fib_entry_hw_flags_set (mlxsw_sp , fib_entry );
4215+ break ;
4216+ case MLXSW_REG_RALUE_OP_WRITE_DELETE :
4217+ mlxsw_sp_fib_entry_hw_flags_clear (mlxsw_sp , fib_entry );
4218+ break ;
42224219 default :
4223- return ;
4220+ break ;
42244221 }
42254222}
42264223
@@ -4447,7 +4444,10 @@ static int mlxsw_sp_fib_entry_op(struct mlxsw_sp *mlxsw_sp,
44474444{
44484445 int err = __mlxsw_sp_fib_entry_op (mlxsw_sp , fib_entry , op );
44494446
4450- mlxsw_sp_fib_entry_offload_refresh (fib_entry , op , err );
4447+ if (err )
4448+ return err ;
4449+
4450+ mlxsw_sp_fib_entry_hw_flags_refresh (mlxsw_sp , fib_entry , op );
44514451
44524452 return err ;
44534453}
@@ -4883,7 +4883,7 @@ mlxsw_sp_router_fib4_replace(struct mlxsw_sp *mlxsw_sp,
48834883 if (!replaced )
48844884 return 0 ;
48854885
4886- mlxsw_sp_fib_entry_offload_unset ( replaced );
4886+ mlxsw_sp_fib_entry_hw_flags_clear ( mlxsw_sp , replaced );
48874887 fib4_replaced = container_of (replaced , struct mlxsw_sp_fib4_entry ,
48884888 common );
48894889 mlxsw_sp_fib4_entry_destroy (mlxsw_sp , fib4_replaced );
@@ -5451,7 +5451,7 @@ static int mlxsw_sp_router_fib6_replace(struct mlxsw_sp *mlxsw_sp,
54515451 if (!replaced )
54525452 return 0 ;
54535453
5454- mlxsw_sp_fib_entry_offload_unset ( replaced );
5454+ mlxsw_sp_fib_entry_hw_flags_clear ( mlxsw_sp , replaced );
54555455 fib6_replaced = container_of (replaced , struct mlxsw_sp_fib6_entry ,
54565456 common );
54575457 mlxsw_sp_fib6_entry_destroy (mlxsw_sp , fib6_replaced );
0 commit comments