Commit d54b70fe authored by Arkadi Sharshevsky's avatar Arkadi Sharshevsky Committed by David S. Miller

mlxsw: spectrum: Add definition for egress rif table

Add definition for egress router interface table. This table describes
the final part in the routing pipeline. This table matches the egress
interface index (rif index, which is set by the previous stages and
determine the out port) and makes the decision of forwarding the packet
towards the L2 logic or dropping it.

The metadata header is added to represent this internal information.
The rif index field is mapped logically to netdevice ifindex.
Signed-off-by: default avatarArkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 230ead01
......@@ -38,20 +38,129 @@
#include "spectrum.h"
#include "spectrum_dpipe.h"
static struct devlink_dpipe_header *mlxsw_dpipe_headers[] = {};
enum mlxsw_sp_field_metadata_id {
MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT,
MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD,
MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP,
};
static struct devlink_dpipe_field mlxsw_sp_dpipe_fields_metadata[] = {
{ .name = "erif_port",
.id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT,
.bitwidth = 32,
.mapping_type = DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX,
},
{ .name = "l3_forward",
.id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD,
.bitwidth = 1,
},
{ .name = "l3_drop",
.id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP,
.bitwidth = 1,
},
};
enum mlxsw_sp_dpipe_header_id {
MLXSW_SP_DPIPE_HEADER_METADATA,
};
static struct devlink_dpipe_header mlxsw_sp_dpipe_header_metadata = {
.name = "mlxsw_meta",
.id = MLXSW_SP_DPIPE_HEADER_METADATA,
.fields = mlxsw_sp_dpipe_fields_metadata,
.fields_count = ARRAY_SIZE(mlxsw_sp_dpipe_fields_metadata),
};
static struct devlink_dpipe_header *mlxsw_dpipe_headers[] = {
&mlxsw_sp_dpipe_header_metadata,
};
static struct devlink_dpipe_headers mlxsw_sp_dpipe_headers = {
.headers = mlxsw_dpipe_headers,
.headers_count = ARRAY_SIZE(mlxsw_dpipe_headers),
};
static int mlxsw_sp_dpipe_table_erif_actions_dump(void *priv,
struct sk_buff *skb)
{
struct devlink_dpipe_action action = {0};
int err;
action.type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
action.header = &mlxsw_sp_dpipe_header_metadata;
action.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_FORWARD;
err = devlink_dpipe_action_put(skb, &action);
if (err)
return err;
action.type = DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY;
action.header = &mlxsw_sp_dpipe_header_metadata;
action.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_L3_DROP;
return devlink_dpipe_action_put(skb, &action);
}
static int mlxsw_sp_dpipe_table_erif_matches_dump(void *priv,
struct sk_buff *skb)
{
struct devlink_dpipe_match match = {0};
match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
match.header = &mlxsw_sp_dpipe_header_metadata;
match.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;
return devlink_dpipe_match_put(skb, &match);
}
static struct devlink_dpipe_table_ops mlxsw_sp_erif_ops = {
.matches_dump = mlxsw_sp_dpipe_table_erif_matches_dump,
.actions_dump = mlxsw_sp_dpipe_table_erif_actions_dump,
};
static int mlxsw_sp_dpipe_erif_table_init(struct mlxsw_sp *mlxsw_sp)
{
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
u64 table_size;
table_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
return devlink_dpipe_table_register(devlink,
MLXSW_SP_DPIPE_TABLE_NAME_ERIF,
&mlxsw_sp_erif_ops,
mlxsw_sp, table_size,
false);
}
static void mlxsw_sp_dpipe_erif_table_fini(struct mlxsw_sp *mlxsw_sp)
{
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
devlink_dpipe_table_unregister(devlink, MLXSW_SP_DPIPE_TABLE_NAME_ERIF);
}
int mlxsw_sp_dpipe_init(struct mlxsw_sp *mlxsw_sp)
{
return devlink_dpipe_headers_register(priv_to_devlink(mlxsw_sp->core),
&mlxsw_sp_dpipe_headers);
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
int err;
err = devlink_dpipe_headers_register(devlink,
&mlxsw_sp_dpipe_headers);
if (err)
return err;
err = mlxsw_sp_dpipe_erif_table_init(mlxsw_sp);
if (err)
goto err_erif_register;
return 0;
err_erif_register:
devlink_dpipe_headers_unregister(priv_to_devlink(mlxsw_sp->core));
return err;
}
void mlxsw_sp_dpipe_fini(struct mlxsw_sp *mlxsw_sp)
{
devlink_dpipe_headers_unregister(priv_to_devlink(mlxsw_sp->core));
struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
mlxsw_sp_dpipe_erif_table_fini(mlxsw_sp);
devlink_dpipe_headers_unregister(devlink);
}
......@@ -38,4 +38,6 @@
int mlxsw_sp_dpipe_init(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_dpipe_fini(struct mlxsw_sp *mlxsw_sp);
#define MLXSW_SP_DPIPE_TABLE_NAME_ERIF "mlxsw_erif"
#endif /* _MLXSW_PIPELINE_H_*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment