Skip to content
This repository has been archived by the owner on Nov 21, 2022. It is now read-only.

Commit

Permalink
Merge branch 'mlxsw-Offload-TC-action-pedit-munge-tcp-udp-sport-dport'
Browse files Browse the repository at this point in the history
Ido Schimmel says:

====================
mlxsw: Offload TC action pedit munge tcp/udp sport/dport

Petr says:

On Spectrum-2 and Spectrum-3, it is possible to overwrite L4 port number of
a TCP or UDP packet in the ACL engine. That corresponds to the pedit munges
of tcp and udp sport resp. dport fields. Offload these munges on the
systems where they are supported.

The current offloading code assumes that all systems support the same set
of fields. This now changes, so in patch #1 first split handling of pedit
munges by chip type. The analysis of which packet field a given munge
describes is kept generic.

Patch #2 introduces the new flexible action fields. Patch #3 then adds the
new pedit fields, and dispatches on them on Spectrum>1.

Patch #4 adds a forwarding selftest for pedit dsfield, applicable to SW as
well as HW datapaths.
====================

Reviewed-by: Jakub Kicinski <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Jun 22, 2020
2 parents 73f782d + 13bd5d0 commit 19430ed
Show file tree
Hide file tree
Showing 6 changed files with 335 additions and 7 deletions.
51 changes: 51 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -1684,3 +1684,54 @@ int mlxsw_afa_block_append_mcrouter(struct mlxsw_afa_block *block,
return 0;
}
EXPORT_SYMBOL(mlxsw_afa_block_append_mcrouter);

/* L4 Port Action
* --------------
* The L4_PORT_ACTION is used for modifying the sport and dport fields of the packet, e.g. for NAT.
* If (the L4 is TCP) or if (the L4 is UDP and checksum field!=0) then the L4 checksum is updated.
*/

#define MLXSW_AFA_L4PORT_CODE 0x12
#define MLXSW_AFA_L4PORT_SIZE 1

enum mlxsw_afa_l4port_s_d {
/* configure src_l4_port */
MLXSW_AFA_L4PORT_S_D_SRC,
/* configure dst_l4_port */
MLXSW_AFA_L4PORT_S_D_DST,
};

/* afa_l4port_s_d
* Source or destination.
*/
MLXSW_ITEM32(afa, l4port, s_d, 0x00, 31, 1);

/* afa_l4port_l4_port
* Number of port to change to.
*/
MLXSW_ITEM32(afa, l4port, l4_port, 0x08, 0, 16);

static void mlxsw_afa_l4port_pack(char *payload, enum mlxsw_afa_l4port_s_d s_d, u16 l4_port)
{
mlxsw_afa_l4port_s_d_set(payload, s_d);
mlxsw_afa_l4port_l4_port_set(payload, l4_port);
}

int mlxsw_afa_block_append_l4port(struct mlxsw_afa_block *block, bool is_dport, u16 l4_port,
struct netlink_ext_ack *extack)
{
enum mlxsw_afa_l4port_s_d s_d = is_dport ? MLXSW_AFA_L4PORT_S_D_DST :
MLXSW_AFA_L4PORT_S_D_SRC;
char *act = mlxsw_afa_block_append_action(block,
MLXSW_AFA_L4PORT_CODE,
MLXSW_AFA_L4PORT_SIZE);

if (IS_ERR(act)) {
NL_SET_ERR_MSG_MOD(extack, "Cannot append L4_PORT action");
return PTR_ERR(act);
}

mlxsw_afa_l4port_pack(act, s_d, l4_port);
return 0;
}
EXPORT_SYMBOL(mlxsw_afa_block_append_l4port);
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,7 @@ int mlxsw_afa_block_append_fid_set(struct mlxsw_afa_block *block, u16 fid,
int mlxsw_afa_block_append_mcrouter(struct mlxsw_afa_block *block,
u16 expected_irif, u16 min_mtu,
bool rmid_valid, u32 kvdl_index);
int mlxsw_afa_block_append_l4port(struct mlxsw_afa_block *block, bool is_dport, u16 l4_port,
struct netlink_ext_ack *extack);

#endif
3 changes: 3 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -4594,6 +4594,7 @@ static int mlxsw_sp1_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->afa_ops = &mlxsw_sp1_act_afa_ops;
mlxsw_sp->afk_ops = &mlxsw_sp1_afk_ops;
mlxsw_sp->mr_tcam_ops = &mlxsw_sp1_mr_tcam_ops;
mlxsw_sp->acl_rulei_ops = &mlxsw_sp1_acl_rulei_ops;
mlxsw_sp->acl_tcam_ops = &mlxsw_sp1_acl_tcam_ops;
mlxsw_sp->nve_ops_arr = mlxsw_sp1_nve_ops_arr;
mlxsw_sp->mac_mask = mlxsw_sp1_mac_mask;
Expand Down Expand Up @@ -4621,6 +4622,7 @@ static int mlxsw_sp2_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->afa_ops = &mlxsw_sp2_act_afa_ops;
mlxsw_sp->afk_ops = &mlxsw_sp2_afk_ops;
mlxsw_sp->mr_tcam_ops = &mlxsw_sp2_mr_tcam_ops;
mlxsw_sp->acl_rulei_ops = &mlxsw_sp2_acl_rulei_ops;
mlxsw_sp->acl_tcam_ops = &mlxsw_sp2_acl_tcam_ops;
mlxsw_sp->nve_ops_arr = mlxsw_sp2_nve_ops_arr;
mlxsw_sp->mac_mask = mlxsw_sp2_mac_mask;
Expand All @@ -4644,6 +4646,7 @@ static int mlxsw_sp3_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->afa_ops = &mlxsw_sp2_act_afa_ops;
mlxsw_sp->afk_ops = &mlxsw_sp2_afk_ops;
mlxsw_sp->mr_tcam_ops = &mlxsw_sp2_mr_tcam_ops;
mlxsw_sp->acl_rulei_ops = &mlxsw_sp2_acl_rulei_ops;
mlxsw_sp->acl_tcam_ops = &mlxsw_sp2_acl_tcam_ops;
mlxsw_sp->nve_ops_arr = mlxsw_sp2_nve_ops_arr;
mlxsw_sp->mac_mask = mlxsw_sp2_mac_mask;
Expand Down
13 changes: 13 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ struct mlxsw_sp_kvdl;
struct mlxsw_sp_nve;
struct mlxsw_sp_kvdl_ops;
struct mlxsw_sp_mr_tcam_ops;
struct mlxsw_sp_acl_rulei_ops;
struct mlxsw_sp_acl_tcam_ops;
struct mlxsw_sp_nve_ops;
struct mlxsw_sp_sb_vals;
Expand Down Expand Up @@ -164,6 +165,7 @@ struct mlxsw_sp {
const struct mlxsw_afa_ops *afa_ops;
const struct mlxsw_afk_ops *afk_ops;
const struct mlxsw_sp_mr_tcam_ops *mr_tcam_ops;
const struct mlxsw_sp_acl_rulei_ops *acl_rulei_ops;
const struct mlxsw_sp_acl_tcam_ops *acl_tcam_ops;
const struct mlxsw_sp_nve_ops **nve_ops_arr;
const struct mlxsw_sp_rif_ops **rif_ops_arr;
Expand Down Expand Up @@ -856,6 +858,17 @@ void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp);
u32 mlxsw_sp_acl_region_rehash_intrvl_get(struct mlxsw_sp *mlxsw_sp);
int mlxsw_sp_acl_region_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp, u32 val);

struct mlxsw_sp_acl_mangle_action;

struct mlxsw_sp_acl_rulei_ops {
int (*act_mangle_field)(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_rule_info *rulei,
struct mlxsw_sp_acl_mangle_action *mact, u32 val,
struct netlink_ext_ack *extack);
};

extern struct mlxsw_sp_acl_rulei_ops mlxsw_sp1_acl_rulei_ops;
extern struct mlxsw_sp_acl_rulei_ops mlxsw_sp2_acl_rulei_ops;

/* spectrum_acl_tcam.c */
struct mlxsw_sp_acl_tcam;
struct mlxsw_sp_acl_tcam_region;
Expand Down
75 changes: 68 additions & 7 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ enum mlxsw_sp_acl_mangle_field {
MLXSW_SP_ACL_MANGLE_FIELD_IP_DSFIELD,
MLXSW_SP_ACL_MANGLE_FIELD_IP_DSCP,
MLXSW_SP_ACL_MANGLE_FIELD_IP_ECN,
MLXSW_SP_ACL_MANGLE_FIELD_IP_SPORT,
MLXSW_SP_ACL_MANGLE_FIELD_IP_DPORT,
};

struct mlxsw_sp_acl_mangle_action {
Expand Down Expand Up @@ -538,13 +540,26 @@ struct mlxsw_sp_acl_mangle_action {
MLXSW_SP_ACL_MANGLE_ACTION(FLOW_ACT_MANGLE_HDR_TYPE_IP6, \
_offset, _mask, _shift, _field)

#define MLXSW_SP_ACL_MANGLE_ACTION_TCP(_offset, _mask, _shift, _field) \
MLXSW_SP_ACL_MANGLE_ACTION(FLOW_ACT_MANGLE_HDR_TYPE_TCP, _offset, _mask, _shift, _field)

#define MLXSW_SP_ACL_MANGLE_ACTION_UDP(_offset, _mask, _shift, _field) \
MLXSW_SP_ACL_MANGLE_ACTION(FLOW_ACT_MANGLE_HDR_TYPE_UDP, _offset, _mask, _shift, _field)

static struct mlxsw_sp_acl_mangle_action mlxsw_sp_acl_mangle_actions[] = {
MLXSW_SP_ACL_MANGLE_ACTION_IP4(0, 0xff00ffff, 16, IP_DSFIELD),
MLXSW_SP_ACL_MANGLE_ACTION_IP4(0, 0xff03ffff, 18, IP_DSCP),
MLXSW_SP_ACL_MANGLE_ACTION_IP4(0, 0xfffcffff, 16, IP_ECN),

MLXSW_SP_ACL_MANGLE_ACTION_IP6(0, 0xf00fffff, 20, IP_DSFIELD),
MLXSW_SP_ACL_MANGLE_ACTION_IP6(0, 0xf03fffff, 22, IP_DSCP),
MLXSW_SP_ACL_MANGLE_ACTION_IP6(0, 0xffcfffff, 20, IP_ECN),

MLXSW_SP_ACL_MANGLE_ACTION_TCP(0, 0x0000ffff, 16, IP_SPORT),
MLXSW_SP_ACL_MANGLE_ACTION_TCP(0, 0xffff0000, 0, IP_DPORT),

MLXSW_SP_ACL_MANGLE_ACTION_UDP(0, 0x0000ffff, 16, IP_SPORT),
MLXSW_SP_ACL_MANGLE_ACTION_UDP(0, 0xffff0000, 0, IP_DPORT),
};

static int
Expand All @@ -563,11 +578,48 @@ mlxsw_sp_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp,
case MLXSW_SP_ACL_MANGLE_FIELD_IP_ECN:
return mlxsw_afa_block_append_qos_ecn(rulei->act_block,
val, extack);
default:
return -EOPNOTSUPP;
}
}

/* We shouldn't have gotten a match in the first place! */
WARN_ONCE(1, "Unhandled mangle field");
return -EINVAL;
static int mlxsw_sp1_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_rule_info *rulei,
struct mlxsw_sp_acl_mangle_action *mact,
u32 val, struct netlink_ext_ack *extack)
{
int err;

err = mlxsw_sp_acl_rulei_act_mangle_field(mlxsw_sp, rulei, mact, val, extack);
if (err != -EOPNOTSUPP)
return err;

NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field");
return err;
}

static int mlxsw_sp2_acl_rulei_act_mangle_field(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_rule_info *rulei,
struct mlxsw_sp_acl_mangle_action *mact,
u32 val, struct netlink_ext_ack *extack)
{
int err;

err = mlxsw_sp_acl_rulei_act_mangle_field(mlxsw_sp, rulei, mact, val, extack);
if (err != -EOPNOTSUPP)
return err;

switch (mact->field) {
case MLXSW_SP_ACL_MANGLE_FIELD_IP_SPORT:
return mlxsw_afa_block_append_l4port(rulei->act_block, false, val, extack);
case MLXSW_SP_ACL_MANGLE_FIELD_IP_DPORT:
return mlxsw_afa_block_append_l4port(rulei->act_block, true, val, extack);
default:
break;
}

NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field");
return err;
}

int mlxsw_sp_acl_rulei_act_mangle(struct mlxsw_sp *mlxsw_sp,
Expand All @@ -576,6 +628,7 @@ int mlxsw_sp_acl_rulei_act_mangle(struct mlxsw_sp *mlxsw_sp,
u32 offset, u32 mask, u32 val,
struct netlink_ext_ack *extack)
{
const struct mlxsw_sp_acl_rulei_ops *acl_rulei_ops = mlxsw_sp->acl_rulei_ops;
struct mlxsw_sp_acl_mangle_action *mact;
size_t i;

Expand All @@ -585,13 +638,13 @@ int mlxsw_sp_acl_rulei_act_mangle(struct mlxsw_sp *mlxsw_sp,
mact->offset == offset &&
mact->mask == mask) {
val >>= mact->shift;
return mlxsw_sp_acl_rulei_act_mangle_field(mlxsw_sp,
rulei, mact,
val, extack);
return acl_rulei_ops->act_mangle_field(mlxsw_sp,
rulei, mact,
val, extack);
}
}

NL_SET_ERR_MSG_MOD(extack, "Unsupported mangle field");
NL_SET_ERR_MSG_MOD(extack, "Unknown mangle field");
return -EINVAL;
}

Expand Down Expand Up @@ -930,3 +983,11 @@ int mlxsw_sp_acl_region_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp, u32 val)
return mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(mlxsw_sp,
&acl->tcam, val);
}

struct mlxsw_sp_acl_rulei_ops mlxsw_sp1_acl_rulei_ops = {
.act_mangle_field = mlxsw_sp1_acl_rulei_act_mangle_field,
};

struct mlxsw_sp_acl_rulei_ops mlxsw_sp2_acl_rulei_ops = {
.act_mangle_field = mlxsw_sp2_acl_rulei_act_mangle_field,
};
Loading

0 comments on commit 19430ed

Please sign in to comment.