drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c
Extension
.c
Size
14860 bytes
Lines
616
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mlx5e_fs_udp {
	struct mlx5e_flow_table tables[FS_UDP_NUM_TYPES];
	struct mlx5_flow_handle *default_rules[FS_UDP_NUM_TYPES];
	int ref_cnt;
};

struct mlx5e_fs_any {
	struct mlx5e_flow_table table;
	struct mlx5_flow_handle *default_rule;
	int ref_cnt;
};

static char *fs_udp_type2str(enum fs_udp_type i)
{
	switch (i) {
	case FS_IPV4_UDP:
		return "UDP v4";
	default: /* FS_IPV6_UDP */
		return "UDP v6";
	}
}

static enum mlx5_traffic_types fs_udp2tt(enum fs_udp_type i)
{
	switch (i) {
	case FS_IPV4_UDP:
		return MLX5_TT_IPV4_UDP;
	default: /* FS_IPV6_UDP */
		return MLX5_TT_IPV6_UDP;
	}
}

static enum fs_udp_type tt2fs_udp(enum mlx5_traffic_types i)
{
	switch (i) {
	case MLX5_TT_IPV4_UDP:
		return FS_IPV4_UDP;
	case MLX5_TT_IPV6_UDP:
		return FS_IPV6_UDP;
	default:
		return FS_UDP_NUM_TYPES;
	}
}

void mlx5e_fs_tt_redirect_del_rule(struct mlx5_flow_handle *rule)
{
	mlx5_del_flow_rules(rule);
}

static void fs_udp_set_dport_flow(struct mlx5_flow_spec *spec, enum fs_udp_type type,
				  u16 udp_dport)
{
	spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
	MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol);
	MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, IPPROTO_UDP);
	MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_version);
	MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_version,
		 type == FS_IPV4_UDP ? 4 : 6);
	MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.udp_dport);
	MLX5_SET(fte_match_param, spec->match_value, outer_headers.udp_dport, udp_dport);
}

struct mlx5_flow_handle *
mlx5e_fs_tt_redirect_udp_add_rule(struct mlx5e_flow_steering *fs,
				  enum mlx5_traffic_types ttc_type,
				  u32 tir_num, u16 d_port)
{
	struct mlx5e_fs_udp *fs_udp = mlx5e_fs_get_udp(fs);
	enum fs_udp_type type = tt2fs_udp(ttc_type);
	struct mlx5_flow_destination dest = {};
	struct mlx5_flow_table *ft = NULL;
	MLX5_DECLARE_FLOW_ACT(flow_act);
	struct mlx5_flow_handle *rule;
	struct mlx5_flow_spec *spec;
	int err;

	if (type == FS_UDP_NUM_TYPES)
		return ERR_PTR(-EINVAL);

	spec = kvzalloc_obj(*spec);
	if (!spec)
		return ERR_PTR(-ENOMEM);

	ft = fs_udp->tables[type].t;

	fs_udp_set_dport_flow(spec, type, d_port);
	dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
	dest.tir_num = tir_num;

	rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);

Annotation

Implementation Notes