Skip to content

Commit ee5a044

Browse files
idoschdavem330
authored andcommitted
mlxsw: spectrum_router: Set hardware flags for routes
Previous patches added support for two hardware flags for IPv4 and IPv6 routes: 'RTM_F_OFFLOAD' and 'RTM_F_TRAP'. Both indicate the presence of the route in hardware. The first indicates that traffic is actually offloaded from the kernel, whereas the second indicates that packets hitting such routes are trapped to the kernel for processing (e.g., host routes). Use these two flags in mlxsw. The flags are modified in two places. Firstly, whenever a route is updated in the device's table. This includes the addition, deletion or update of a route. For example, when a host route is promoted to perform NVE decapsulation, its action in the device is updated, the 'RTM_F_OFFLOAD' flag set and the 'RTM_F_TRAP' flag cleared. Secondly, when a route is replaced and overwritten by another route, its flags are cleared. v2: * Convert to new fib_alias_hw_flags_set() interface Signed-off-by: Ido Schimmel <[email protected]> Acked-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8c5a5b9 commit ee5a044

File tree

1 file changed

+77
-77
lines changed

1 file changed

+77
-77
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

Lines changed: 77 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4096,131 +4096,128 @@ mlxsw_sp_rt6_nexthop(struct mlxsw_sp_nexthop_group *nh_grp,
40964096
}
40974097

40984098
static 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

41224123
static 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

41384146
static 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

41674166
static 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

41944193
static 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

42074207
static 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

Comments
 (0)