@@ -219,6 +219,28 @@ mlx5e_tc_match_to_reg_match(struct mlx5_flow_spec *spec,
219219 spec -> match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_2 ;
220220}
221221
222+ void
223+ mlx5e_tc_match_to_reg_get_match (struct mlx5_flow_spec * spec ,
224+ enum mlx5e_tc_attr_to_reg type ,
225+ u32 * data ,
226+ u32 * mask )
227+ {
228+ int soffset = mlx5e_tc_attr_to_reg_mappings [type ].soffset ;
229+ int match_len = mlx5e_tc_attr_to_reg_mappings [type ].mlen ;
230+ void * headers_c = spec -> match_criteria ;
231+ void * headers_v = spec -> match_value ;
232+ void * fmask , * fval ;
233+
234+ fmask = headers_c + soffset ;
235+ fval = headers_v + soffset ;
236+
237+ memcpy (mask , fmask , match_len );
238+ memcpy (data , fval , match_len );
239+
240+ * mask = be32_to_cpu ((__force __be32 )(* mask << (32 - (match_len * 8 ))));
241+ * data = be32_to_cpu ((__force __be32 )(* data << (32 - (match_len * 8 ))));
242+ }
243+
222244int
223245mlx5e_tc_match_to_reg_set (struct mlx5_core_dev * mdev ,
224246 struct mlx5e_tc_mod_hdr_acts * mod_hdr_acts ,
@@ -3086,6 +3108,7 @@ struct ipv6_hoplimit_word {
30863108
30873109static int is_action_keys_supported (const struct flow_action_entry * act ,
30883110 bool ct_flow , bool * modify_ip_header ,
3111+ bool * modify_tuple ,
30893112 struct netlink_ext_ack * extack )
30903113{
30913114 u32 mask , offset ;
@@ -3108,7 +3131,10 @@ static int is_action_keys_supported(const struct flow_action_entry *act,
31083131 * modify_ip_header = true;
31093132 }
31103133
3111- if (ct_flow && offset >= offsetof(struct iphdr , saddr )) {
3134+ if (offset >= offsetof(struct iphdr , saddr ))
3135+ * modify_tuple = true;
3136+
3137+ if (ct_flow && * modify_tuple ) {
31123138 NL_SET_ERR_MSG_MOD (extack ,
31133139 "can't offload re-write of ipv4 address with action ct" );
31143140 return - EOPNOTSUPP ;
@@ -3123,16 +3149,22 @@ static int is_action_keys_supported(const struct flow_action_entry *act,
31233149 * modify_ip_header = true;
31243150 }
31253151
3126- if (ct_flow && offset >= offsetof(struct ipv6hdr , saddr )) {
3152+ if (ct_flow && offset >= offsetof(struct ipv6hdr , saddr ))
3153+ * modify_tuple = true;
3154+
3155+ if (ct_flow && * modify_tuple ) {
31273156 NL_SET_ERR_MSG_MOD (extack ,
31283157 "can't offload re-write of ipv6 address with action ct" );
31293158 return - EOPNOTSUPP ;
31303159 }
3131- } else if (ct_flow && (htype == FLOW_ACT_MANGLE_HDR_TYPE_TCP ||
3132- htype == FLOW_ACT_MANGLE_HDR_TYPE_UDP )) {
3133- NL_SET_ERR_MSG_MOD (extack ,
3134- "can't offload re-write of transport header ports with action ct" );
3135- return - EOPNOTSUPP ;
3160+ } else if (htype == FLOW_ACT_MANGLE_HDR_TYPE_TCP ||
3161+ htype == FLOW_ACT_MANGLE_HDR_TYPE_UDP ) {
3162+ * modify_tuple = true;
3163+ if (ct_flow ) {
3164+ NL_SET_ERR_MSG_MOD (extack ,
3165+ "can't offload re-write of transport header ports with action ct" );
3166+ return - EOPNOTSUPP ;
3167+ }
31363168 }
31373169
31383170 return 0 ;
@@ -3142,10 +3174,11 @@ static bool modify_header_match_supported(struct mlx5e_priv *priv,
31423174 struct mlx5_flow_spec * spec ,
31433175 struct flow_action * flow_action ,
31443176 u32 actions , bool ct_flow ,
3177+ bool ct_clear ,
31453178 struct netlink_ext_ack * extack )
31463179{
31473180 const struct flow_action_entry * act ;
3148- bool modify_ip_header ;
3181+ bool modify_ip_header , modify_tuple ;
31493182 void * headers_c ;
31503183 void * headers_v ;
31513184 u16 ethertype ;
@@ -3162,17 +3195,32 @@ static bool modify_header_match_supported(struct mlx5e_priv *priv,
31623195 goto out_ok ;
31633196
31643197 modify_ip_header = false;
3198+ modify_tuple = false;
31653199 flow_action_for_each (i , act , flow_action ) {
31663200 if (act -> id != FLOW_ACTION_MANGLE &&
31673201 act -> id != FLOW_ACTION_ADD )
31683202 continue ;
31693203
31703204 err = is_action_keys_supported (act , ct_flow ,
3171- & modify_ip_header , extack );
3205+ & modify_ip_header ,
3206+ & modify_tuple , extack );
31723207 if (err )
31733208 return err ;
31743209 }
31753210
3211+ /* Add ct_state=-trk match so it will be offloaded for non ct flows
3212+ * (or after clear action), as otherwise, since the tuple is changed,
3213+ * we can't restore ct state
3214+ */
3215+ if (!ct_clear && modify_tuple &&
3216+ mlx5_tc_ct_add_no_trk_match (priv , spec )) {
3217+ NL_SET_ERR_MSG_MOD (extack ,
3218+ "can't offload tuple modify header with ct matches" );
3219+ netdev_info (priv -> netdev ,
3220+ "can't offload tuple modify header with ct matches" );
3221+ return false;
3222+ }
3223+
31763224 ip_proto = MLX5_GET (fte_match_set_lyr_2_4 , headers_v , ip_protocol );
31773225 if (modify_ip_header && ip_proto != IPPROTO_TCP &&
31783226 ip_proto != IPPROTO_UDP && ip_proto != IPPROTO_ICMP ) {
@@ -3216,7 +3264,8 @@ static bool actions_match_supported(struct mlx5e_priv *priv,
32163264 if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR )
32173265 return modify_header_match_supported (priv , & parse_attr -> spec ,
32183266 flow_action , actions ,
3219- ct_flow , extack );
3267+ ct_flow , ct_clear ,
3268+ extack );
32203269
32213270 return true;
32223271}
@@ -4483,11 +4532,12 @@ __mlx5e_add_fdb_flow(struct mlx5e_priv *priv,
44834532 if (err )
44844533 goto err_free ;
44854534
4486- err = parse_tc_fdb_actions (priv , & rule -> action , flow , extack , filter_dev );
4535+ /* actions validation depends on parsing the ct matches first */
4536+ err = mlx5_tc_ct_parse_match (priv , & parse_attr -> spec , f , extack );
44874537 if (err )
44884538 goto err_free ;
44894539
4490- err = mlx5_tc_ct_parse_match (priv , & parse_attr -> spec , f , extack );
4540+ err = parse_tc_fdb_actions (priv , & rule -> action , flow , extack , filter_dev );
44914541 if (err )
44924542 goto err_free ;
44934543
0 commit comments