mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	net/mlx5e: IPsec, support upper protocol selector field offload
Add support to policy/state upper protocol selector field offload, this will enable to select traffic for IPsec operation based on l4 protocol (TCP/UDP) with specific source/destination port. Signed-off-by: Raed Salem <raeds@nvidia.com> Reviewed-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
This commit is contained in:
		
							parent
							
								
									ce231772da
								
							
						
					
					
						commit
						a7385187a3
					
				
					 3 changed files with 56 additions and 0 deletions
				
			
		| 
						 | 
					@ -158,6 +158,11 @@ void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
 | 
				
			||||||
	attrs->family = x->props.family;
 | 
						attrs->family = x->props.family;
 | 
				
			||||||
	attrs->type = x->xso.type;
 | 
						attrs->type = x->xso.type;
 | 
				
			||||||
	attrs->reqid = x->props.reqid;
 | 
						attrs->reqid = x->props.reqid;
 | 
				
			||||||
 | 
						attrs->upspec.dport = ntohs(x->sel.dport);
 | 
				
			||||||
 | 
						attrs->upspec.dport_mask = ntohs(x->sel.dport_mask);
 | 
				
			||||||
 | 
						attrs->upspec.sport = ntohs(x->sel.sport);
 | 
				
			||||||
 | 
						attrs->upspec.sport_mask = ntohs(x->sel.sport_mask);
 | 
				
			||||||
 | 
						attrs->upspec.proto = x->sel.proto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mlx5e_ipsec_init_limits(sa_entry, attrs);
 | 
						mlx5e_ipsec_init_limits(sa_entry, attrs);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -221,6 +226,13 @@ static int mlx5e_xfrm_validate_state(struct mlx5_core_dev *mdev,
 | 
				
			||||||
		NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states with geniv other than seqiv");
 | 
							NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states with geniv other than seqiv");
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (x->sel.proto != IPPROTO_IP &&
 | 
				
			||||||
 | 
						    (x->sel.proto != IPPROTO_UDP || x->xso.dir != XFRM_DEV_OFFLOAD_OUT)) {
 | 
				
			||||||
 | 
							NL_SET_ERR_MSG_MOD(extack, "Device does not support upper protocol other than UDP, and only Tx direction");
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (x->xso.type) {
 | 
						switch (x->xso.type) {
 | 
				
			||||||
	case XFRM_DEV_OFFLOAD_CRYPTO:
 | 
						case XFRM_DEV_OFFLOAD_CRYPTO:
 | 
				
			||||||
		if (!(mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO)) {
 | 
							if (!(mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO)) {
 | 
				
			||||||
| 
						 | 
					@ -517,6 +529,12 @@ static int mlx5e_xfrm_validate_policy(struct xfrm_policy *x,
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (x->selector.proto != IPPROTO_IP &&
 | 
				
			||||||
 | 
						    (x->selector.proto != IPPROTO_UDP || x->xdo.dir != XFRM_DEV_OFFLOAD_OUT)) {
 | 
				
			||||||
 | 
							NL_SET_ERR_MSG_MOD(extack, "Device does not support upper protocol other than UDP, and only Tx direction");
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -537,6 +555,11 @@ mlx5e_ipsec_build_accel_pol_attrs(struct mlx5e_ipsec_pol_entry *pol_entry,
 | 
				
			||||||
	attrs->action = x->action;
 | 
						attrs->action = x->action;
 | 
				
			||||||
	attrs->type = XFRM_DEV_OFFLOAD_PACKET;
 | 
						attrs->type = XFRM_DEV_OFFLOAD_PACKET;
 | 
				
			||||||
	attrs->reqid = x->xfrm_vec[0].reqid;
 | 
						attrs->reqid = x->xfrm_vec[0].reqid;
 | 
				
			||||||
 | 
						attrs->upspec.dport = ntohs(sel->dport);
 | 
				
			||||||
 | 
						attrs->upspec.dport_mask = ntohs(sel->dport_mask);
 | 
				
			||||||
 | 
						attrs->upspec.sport = ntohs(sel->sport);
 | 
				
			||||||
 | 
						attrs->upspec.sport_mask = ntohs(sel->sport_mask);
 | 
				
			||||||
 | 
						attrs->upspec.proto = sel->proto;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
 | 
					static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,6 +52,14 @@ struct aes_gcm_keymat {
 | 
				
			||||||
	u32   aes_key[256 / 32];
 | 
						u32   aes_key[256 / 32];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct upspec {
 | 
				
			||||||
 | 
						u16 dport;
 | 
				
			||||||
 | 
						u16 dport_mask;
 | 
				
			||||||
 | 
						u16 sport;
 | 
				
			||||||
 | 
						u16 sport_mask;
 | 
				
			||||||
 | 
						u8 proto;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mlx5_accel_esp_xfrm_attrs {
 | 
					struct mlx5_accel_esp_xfrm_attrs {
 | 
				
			||||||
	u32   esn;
 | 
						u32   esn;
 | 
				
			||||||
	u32   spi;
 | 
						u32   spi;
 | 
				
			||||||
| 
						 | 
					@ -68,6 +76,7 @@ struct mlx5_accel_esp_xfrm_attrs {
 | 
				
			||||||
		__be32 a6[4];
 | 
							__be32 a6[4];
 | 
				
			||||||
	} daddr;
 | 
						} daddr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct upspec upspec;
 | 
				
			||||||
	u8 dir : 2;
 | 
						u8 dir : 2;
 | 
				
			||||||
	u8 esn_overlap : 1;
 | 
						u8 esn_overlap : 1;
 | 
				
			||||||
	u8 esn_trigger : 1;
 | 
						u8 esn_trigger : 1;
 | 
				
			||||||
| 
						 | 
					@ -181,6 +190,7 @@ struct mlx5_accel_pol_xfrm_attrs {
 | 
				
			||||||
		__be32 a6[4];
 | 
							__be32 a6[4];
 | 
				
			||||||
	} daddr;
 | 
						} daddr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct upspec upspec;
 | 
				
			||||||
	u8 family;
 | 
						u8 family;
 | 
				
			||||||
	u8 action;
 | 
						u8 action;
 | 
				
			||||||
	u8 type : 2;
 | 
						u8 type : 2;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -467,6 +467,27 @@ static void setup_fte_reg_c0(struct mlx5_flow_spec *spec, u32 reqid)
 | 
				
			||||||
		 misc_parameters_2.metadata_reg_c_0, reqid);
 | 
							 misc_parameters_2.metadata_reg_c_0, reqid);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void setup_fte_upper_proto_match(struct mlx5_flow_spec *spec, struct upspec *upspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (upspec->proto != IPPROTO_UDP)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS;
 | 
				
			||||||
 | 
						MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, spec->match_criteria, ip_protocol);
 | 
				
			||||||
 | 
						MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, ip_protocol, upspec->proto);
 | 
				
			||||||
 | 
						if (upspec->dport) {
 | 
				
			||||||
 | 
							MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria, udp_dport,
 | 
				
			||||||
 | 
								 upspec->dport_mask);
 | 
				
			||||||
 | 
							MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, udp_dport, upspec->dport);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (upspec->sport) {
 | 
				
			||||||
 | 
							MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria, udp_dport,
 | 
				
			||||||
 | 
								 upspec->sport_mask);
 | 
				
			||||||
 | 
							MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, udp_dport, upspec->sport);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int setup_modify_header(struct mlx5_core_dev *mdev, u32 val, u8 dir,
 | 
					static int setup_modify_header(struct mlx5_core_dev *mdev, u32 val, u8 dir,
 | 
				
			||||||
			       struct mlx5_flow_act *flow_act)
 | 
								       struct mlx5_flow_act *flow_act)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -654,6 +675,7 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
 | 
				
			||||||
		setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
 | 
							setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setup_fte_no_frags(spec);
 | 
						setup_fte_no_frags(spec);
 | 
				
			||||||
 | 
						setup_fte_upper_proto_match(spec, &attrs->upspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (attrs->type) {
 | 
						switch (attrs->type) {
 | 
				
			||||||
	case XFRM_DEV_OFFLOAD_CRYPTO:
 | 
						case XFRM_DEV_OFFLOAD_CRYPTO:
 | 
				
			||||||
| 
						 | 
					@ -728,6 +750,7 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
 | 
				
			||||||
		setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
 | 
							setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setup_fte_no_frags(spec);
 | 
						setup_fte_no_frags(spec);
 | 
				
			||||||
 | 
						setup_fte_upper_proto_match(spec, &attrs->upspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = setup_modify_header(mdev, attrs->reqid, XFRM_DEV_OFFLOAD_OUT,
 | 
						err = setup_modify_header(mdev, attrs->reqid, XFRM_DEV_OFFLOAD_OUT,
 | 
				
			||||||
				  &flow_act);
 | 
									  &flow_act);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue