diff --git a/providers/mlx5/dr_action.c b/providers/mlx5/dr_action.c index 1330457f2..5f457fab1 100644 --- a/providers/mlx5/dr_action.c +++ b/providers/mlx5/dr_action.c @@ -338,6 +338,9 @@ static const struct dr_action_modify_field_conv dr_action_conv_arr[] = { [MLX5_ACTION_IN_FIELD_OUT_TCP_ACK_NUM] = { .hw_field = MLX5_DR_ACTION_MDFY_HW_FLD_L4_1, .start = 0, .end = 31, }, + [MLX5_ACTION_IN_FIELD_OUT_FIRST_VID] = { + .hw_field = MLX5_DR_ACTION_MDFY_HW_FLD_L2_2, .start = 0, .end = 15, + }, }; struct dr_action_apply_attr { diff --git a/providers/mlx5/dr_matcher.c b/providers/mlx5/dr_matcher.c index 992884549..247c73f1d 100644 --- a/providers/mlx5/dr_matcher.c +++ b/providers/mlx5/dr_matcher.c @@ -183,6 +183,26 @@ dr_mask_is_flex_parser_tnl_geneve_set(struct dr_match_param *mask, dr_matcher_supp_flex_parser_geneve(&dmn->info.caps); } +static bool dr_mask_is_misc3_gtpu_set(struct dr_match_misc3 *misc3) +{ + return misc3->gtpu_flags || + misc3->gtpu_msg_type || + misc3->gtpu_teid; +} + +static bool dr_matcher_supp_flex_parser_gtpu(struct dr_devx_caps *caps) +{ + return caps->flex_protocols & + MLX5_FLEX_PARSER_GTPU_ENABLED; +} + +static bool dr_mask_is_flex_parser_tnl_gtpu_set(struct dr_match_param *mask, + struct mlx5dv_dr_domain *dmn) +{ + return dr_mask_is_misc3_gtpu_set(&mask->misc3) && + dr_matcher_supp_flex_parser_gtpu(&dmn->info.caps); +} + static bool dr_mask_is_flex_parser_icmpv6_set(struct dr_match_misc3 *misc3) { return (misc3->icmpv6_type || misc3->icmpv6_code || @@ -316,6 +336,9 @@ static int dr_matcher_set_ste_builders(struct mlx5dv_dr_matcher *matcher, else if (dr_mask_is_flex_parser_tnl_geneve_set(&mask, dmn)) dr_ste_build_flex_parser_tnl_geneve(&sb[idx++], &mask, inner, rx); + else if (dr_mask_is_flex_parser_tnl_gtpu_set(&mask, dmn)) + dr_ste_build_flex_parser_tnl_gtpu(&sb[idx++], &mask, + inner, rx); if (DR_MASK_IS_ETH_L4_MISC_SET(mask.misc3, outer)) dr_ste_build_eth_l4_misc(&sb[idx++], &mask, inner, rx); @@ -679,7 +702,7 @@ static int dr_matcher_init(struct mlx5dv_dr_matcher *matcher, } if (mask) { - if (mask->match_sz > sizeof(struct dr_match_param)) { + if (mask->match_sz > DEVX_ST_SZ_BYTES(dr_match_param)) { dr_dbg(dmn, "Invalid match size attribute\n"); errno = EINVAL; return errno; diff --git a/providers/mlx5/dr_rule.c b/providers/mlx5/dr_rule.c index 46d0c2301..a15c13c02 100644 --- a/providers/mlx5/dr_rule.c +++ b/providers/mlx5/dr_rule.c @@ -886,7 +886,7 @@ static bool dr_rule_verify(struct mlx5dv_dr_matcher *matcher, uint32_t s_idx, e_idx; if (!value_size || - (value_size > sizeof(struct dr_match_param) || + (value_size > DEVX_ST_SZ_BYTES(dr_match_param) || (value_size % sizeof(uint32_t)))) { dr_dbg(dmn, "Rule parameters length is incorrect\n"); errno = EINVAL; diff --git a/providers/mlx5/dr_ste.c b/providers/mlx5/dr_ste.c index 1b79dd34f..4a3d8b291 100644 --- a/providers/mlx5/dr_ste.c +++ b/providers/mlx5/dr_ste.c @@ -1036,6 +1036,9 @@ static void dr_ste_copy_mask_misc3(char *mask, struct dr_match_misc3 *spec) spec->icmpv4_code = DEVX_GET(dr_match_set_misc3, mask, icmp_code); spec->icmpv6_type = DEVX_GET(dr_match_set_misc3, mask, icmpv6_type); spec->icmpv6_code = DEVX_GET(dr_match_set_misc3, mask, icmpv6_code); + spec->gtpu_flags = DEVX_GET(dr_match_set_misc3, mask, gtpu_flags); + spec->gtpu_msg_type = DEVX_GET(dr_match_set_misc3, mask, gtpu_msg_type); + spec->gtpu_teid = DEVX_GET(dr_match_set_misc3, mask, gtpu_teid); } #define MAX_PARAM_SIZE 512 @@ -1050,7 +1053,7 @@ void dr_ste_copy_param(uint8_t match_criteria, void *buff; if (match_criteria & DR_MATCHER_CRITERIA_OUTER) { - if (mask->match_sz < sizeof(struct dr_match_spec)) { + if (mask->match_sz < DEVX_ST_SZ_BYTES(dr_match_spec)) { memcpy(tail_param, data, mask->match_sz); buff = tail_param; } else { @@ -1058,11 +1061,11 @@ void dr_ste_copy_param(uint8_t match_criteria, } dr_ste_copy_mask_spec(buff, &set_param->outer); } - param_location = sizeof(struct dr_match_spec); + param_location = DEVX_ST_SZ_BYTES(dr_match_spec); if (match_criteria & DR_MATCHER_CRITERIA_MISC) { if (mask->match_sz < param_location + - sizeof(struct dr_match_misc)) { + DEVX_ST_SZ_BYTES(dr_match_set_misc)) { memcpy(tail_param, data + param_location, mask->match_sz - param_location); buff = tail_param; @@ -1071,11 +1074,11 @@ void dr_ste_copy_param(uint8_t match_criteria, } dr_ste_copy_mask_misc(buff, &set_param->misc); } - param_location += sizeof(struct dr_match_misc); + param_location += DEVX_ST_SZ_BYTES(dr_match_set_misc); if (match_criteria & DR_MATCHER_CRITERIA_INNER) { if (mask->match_sz < param_location + - sizeof(struct dr_match_spec)) { + DEVX_ST_SZ_BYTES(dr_match_spec)) { memcpy(tail_param, data + param_location, mask->match_sz - param_location); buff = tail_param; @@ -1084,11 +1087,11 @@ void dr_ste_copy_param(uint8_t match_criteria, } dr_ste_copy_mask_spec(buff, &set_param->inner); } - param_location += sizeof(struct dr_match_spec); + param_location += DEVX_ST_SZ_BYTES(dr_match_spec); if (match_criteria & DR_MATCHER_CRITERIA_MISC2) { if (mask->match_sz < param_location + - sizeof(struct dr_match_misc2)) { + DEVX_ST_SZ_BYTES(dr_match_set_misc2)) { memcpy(tail_param, data + param_location, mask->match_sz - param_location); buff = tail_param; @@ -1098,11 +1101,11 @@ void dr_ste_copy_param(uint8_t match_criteria, dr_ste_copy_mask_misc2(buff, &set_param->misc2); } - param_location += sizeof(struct dr_match_misc2); + param_location += DEVX_ST_SZ_BYTES(dr_match_set_misc2); if (match_criteria & DR_MATCHER_CRITERIA_MISC3) { if (mask->match_sz < param_location + - sizeof(struct dr_match_misc3)) { + DEVX_ST_SZ_BYTES(dr_match_set_misc3)) { memcpy(tail_param, data + param_location, mask->match_sz - param_location); buff = tail_param; @@ -2230,6 +2233,57 @@ void dr_ste_build_flex_parser_tnl_geneve(struct dr_ste_build *sb, sb->ste_build_tag_func = &dr_ste_build_flex_parser_tnl_geneve_tag; } +static void +dr_ste_build_flex_parser_tnl_gtpu_bit_mask(struct dr_match_param *value, + uint8_t *bit_mask) +{ + struct dr_match_misc3 *misc3 = &value->misc3; + + DR_STE_SET_MASK_V(flex_parser_tnl_gtpu, bit_mask, + gtpu_flags, misc3, + gtpu_flags); + DR_STE_SET_MASK_V(flex_parser_tnl_gtpu, bit_mask, + gtpu_msg_type, misc3, + gtpu_msg_type); + DR_STE_SET_MASK_V(flex_parser_tnl_gtpu, bit_mask, + gtpu_teid, misc3, + gtpu_teid); +} + +static int +dr_ste_build_flex_parser_tnl_gtpu_tag(struct dr_match_param *value, + struct dr_ste_build *sb, + uint8_t *hw_ste_p) +{ + struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p; + struct dr_match_misc3 *misc3 = &value->misc3; + uint8_t *tag = hw_ste->tag; + + DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, + gtpu_flags, misc3, + gtpu_flags); + DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, + gtpu_msg_type, misc3, + gtpu_msg_type); + DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, + gtpu_teid, misc3, + gtpu_teid); + + return 0; +} + +void dr_ste_build_flex_parser_tnl_gtpu(struct dr_ste_build *sb, + struct dr_match_param *mask, + bool inner, bool rx) +{ + dr_ste_build_flex_parser_tnl_gtpu_bit_mask(mask, sb->bit_mask); + sb->rx = rx; + sb->inner = inner; + sb->lu_type = DR_STE_LU_TYPE_FLEX_PARSER_TNL_HEADER; + sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask); + sb->ste_build_tag_func = &dr_ste_build_flex_parser_tnl_gtpu_tag; +} + static void dr_ste_build_register_0_bit_mask(struct dr_match_param *value, uint8_t *bit_mask) { diff --git a/providers/mlx5/mlx5_ifc.h b/providers/mlx5/mlx5_ifc.h index 03d70f5e5..79acde9a8 100644 --- a/providers/mlx5/mlx5_ifc.h +++ b/providers/mlx5/mlx5_ifc.h @@ -447,7 +447,24 @@ struct mlx5_ifc_dr_match_set_misc3_bits { u8 icmpv6_type[0x8]; u8 icmpv6_code[0x8]; - u8 reserved_at_120[0xe0]; + u8 reserved_at_120[0x20]; + + u8 gtpu_teid[0x20]; + + u8 gtpu_msg_type[0x8]; + u8 reserved_at_148[0x5]; + u8 gtpu_flags[0x3]; + u8 reserved_at_150[0x10]; + + u8 reserved_at_160[0x80]; +}; + +struct mlx5_ifc_dr_match_param_bits { + struct mlx5_ifc_dr_match_spec_bits outer; + struct mlx5_ifc_dr_match_set_misc_bits misc; + struct mlx5_ifc_dr_match_spec_bits inner; + struct mlx5_ifc_dr_match_set_misc2_bits misc2; + struct mlx5_ifc_dr_match_set_misc3_bits misc3; }; struct mlx5_ifc_flow_table_prop_layout_bits { @@ -506,6 +523,7 @@ enum { MLX5_FLEX_PARSER_VXLAN_GPE_ENABLED = 1 << 7, MLX5_FLEX_PARSER_ICMP_V4_ENABLED = 1 << 8, MLX5_FLEX_PARSER_ICMP_V6_ENABLED = 1 << 9, + MLX5_FLEX_PARSER_GTPU_ENABLED = 1 << 11, }; struct mlx5_ifc_cmd_hca_cap_bits { @@ -1622,6 +1640,17 @@ struct mlx5_ifc_ste_flex_parser_tnl_geneve_bits { u8 reserved_at_40[0x40]; }; +struct mlx5_ifc_ste_flex_parser_tnl_gtpu_bits { + u8 reserved_at_0[0x5]; + u8 gtpu_flags[0x3]; + u8 gtpu_msg_type[0x8]; + u8 reserved_at_10[0x10]; + + u8 gtpu_teid[0x20]; + + u8 reserved_at_40[0x40]; +}; + struct mlx5_ifc_ste_general_purpose_bits { u8 general_purpose_lookup_field[0x20]; @@ -1711,6 +1740,7 @@ enum { MLX5_ACTION_IN_FIELD_OUT_DIPV6_31_0 = 0x14, MLX5_ACTION_IN_FIELD_OUT_SIPV4 = 0x15, MLX5_ACTION_IN_FIELD_OUT_DIPV4 = 0x16, + MLX5_ACTION_IN_FIELD_OUT_FIRST_VID = 0x17, MLX5_ACTION_IN_FIELD_OUT_IPV6_HOPLIMIT = 0x47, MLX5_ACTION_IN_FIELD_OUT_METADATA_REGA = 0x49, MLX5_ACTION_IN_FIELD_OUT_METADATA_REGB = 0x50, diff --git a/providers/mlx5/mlx5dv_dr.h b/providers/mlx5/mlx5dv_dr.h index f862c47ac..640ab5dd6 100644 --- a/providers/mlx5/mlx5dv_dr.h +++ b/providers/mlx5/mlx5dv_dr.h @@ -406,6 +406,9 @@ void dr_ste_build_flex_parser_tnl_vxlan_gpe(struct dr_ste_build *sb, void dr_ste_build_flex_parser_tnl_geneve(struct dr_ste_build *sb, struct dr_match_param *mask, bool inner, bool rx); +void dr_ste_build_flex_parser_tnl_gtpu(struct dr_ste_build *sb, + struct dr_match_param *mask, + bool inner, bool rx); void dr_ste_build_general_purpose(struct dr_ste_build *sb, struct dr_match_param *mask, bool inner, bool rx); @@ -454,7 +457,6 @@ struct dr_match_spec { uint32_t tcp_dport:16; /* TCP destination port. ;tcp and udp sport/dport are mutually exclusive */ uint32_t tcp_sport:16; /* TCP source port.;tcp and udp sport/dport are mutually exclusive */ uint32_t ip_ttl_hoplimit:8; - uint32_t reserved:24; uint32_t udp_dport:16; /* UDP destination port.;tcp and udp sport/dport are mutually exclusive */ uint32_t udp_sport:16; /* UDP source port.;tcp and udp sport/dport are mutually exclusive */ uint32_t src_ip_127_96; /* IPv6 source address of incoming packets ;For IPv4 address use bits 31:0 (rest of the bits are reserved);This field should be qualified by an appropriate ;ethertype */ @@ -472,10 +474,8 @@ struct dr_match_misc { uint32_t source_vhca_port:4; uint32_t gre_s_present:1; /* used with GRE, sequence number exist when gre_s_present == 1 */ uint32_t gre_k_present:1; /* used with GRE, key exist when gre_k_present == 1 */ - uint32_t reserved_auto1:1; uint32_t gre_c_present:1; /* used with GRE, checksum exist when gre_c_present == 1 */ uint32_t source_port:16; /* Source port.;0xffff determines wire port */ - uint32_t reserved_auto2:16; uint32_t inner_second_vid:12; /* VLAN ID of first VLAN tag the inner header of the incoming packet. ;Valid only when inner_second_cvlan_tag ==1 or inner_sec;ond_svlan_tag ==1 */ uint32_t inner_second_cfi:1; /* CFI bit of first VLAN tag in the inner header of the incoming packet. ;Valid only when inner_second_cvlan_tag ==1 or inner_sec;ond_svlan_tag ==1 */ uint32_t inner_second_prio:3; /* Priority of second VLAN tag in the inner header of the incoming ;packet. Valid only when inner_second_cvlan_tag ==1 or inner_sec;ond_svlan_tag ==1 */ @@ -483,28 +483,20 @@ struct dr_match_misc { uint32_t outer_second_cfi:1; /* CFI bit of first VLAN tag in the outer header of the incoming packet. ;Valid only when outer_second_cvlan_tag ==1 or outer_sec;ond_svlan_tag ==1 */ uint32_t outer_second_prio:3; /* Priority of second VLAN tag in the outer header of the incoming ;packet. Valid only when outer_second_cvlan_tag ==1 or outer_sec;ond_svlan_tag ==1 */ uint32_t gre_protocol:16; /* GRE Protocol (outer) */ - uint32_t reserved_auto3:12; uint32_t inner_second_svlan_tag:1; /* The second vlan in the inner header of the packet is s-vlan (0x8a88). ;inner_second_cvlan_tag and inner_second_svlan_tag cannot be set ;together */ uint32_t outer_second_svlan_tag:1; /* The second vlan in the outer header of the packet is s-vlan (0x8a88). ;outer_second_cvlan_tag and outer_second_svlan_tag cannot be set ;together */ uint32_t inner_second_cvlan_tag:1; /* The second vlan in the inner header of the packet is c-vlan (0x8100). ;inner_second_cvlan_tag and inner_second_svlan_tag cannot be set ;together */ uint32_t outer_second_cvlan_tag:1; /* The second vlan in the outer header of the packet is c-vlan (0x8100). ;outer_second_cvlan_tag and outer_second_svlan_tag cannot be set ;together */ uint32_t gre_key_l:8; /* GRE Key [7:0] (outer) */ uint32_t gre_key_h:24; /* GRE Key[31:8] (outer) */ - uint32_t reserved_auto4:8; uint32_t vxlan_vni:24; /* VXLAN VNI (outer) */ uint32_t geneve_oam:1; /* GENEVE OAM field (outer) */ - uint32_t reserved_auto5:7; uint32_t geneve_vni:24; /* GENEVE VNI field (outer) */ uint32_t outer_ipv6_flow_label:20; /* Flow label of incoming IPv6 packet (outer) */ - uint32_t reserved_auto6:12; uint32_t inner_ipv6_flow_label:20; /* Flow label of incoming IPv6 packet (inner) */ - uint32_t reserved_auto7:12; uint32_t geneve_protocol_type:16; /* GENEVE protocol type (outer) */ uint32_t geneve_opt_len:6; /* GENEVE OptLen (outer) */ - uint32_t reserved_auto8:10; uint32_t bth_dst_qp:24; /* Destination QP in BTH header */ - uint32_t reserved_auto9:8; - uint8_t reserved_auto10[20]; }; struct dr_match_misc2 { @@ -534,7 +526,6 @@ struct dr_match_misc2 { uint32_t metadata_reg_c_0; /* metadata_reg_c_0 */ uint32_t metadata_reg_a; /* metadata_reg_a */ uint32_t metadata_reg_b; /* metadata_reg_b */ - uint8_t reserved_auto2[8]; }; struct dr_match_misc3 { @@ -543,8 +534,6 @@ struct dr_match_misc3 { uint32_t inner_tcp_ack_num; uint32_t outer_tcp_ack_num; uint32_t outer_vxlan_gpe_vni:24; - uint32_t reserved_auto1:8; - uint32_t reserved_auto2:16; uint32_t outer_vxlan_gpe_flags:8; uint32_t outer_vxlan_gpe_next_protocol:8; uint32_t icmpv4_header_data; @@ -553,7 +542,9 @@ struct dr_match_misc3 { uint32_t icmpv6_type:8; uint32_t icmpv4_code:8; uint32_t icmpv4_type:8; - uint8_t reserved_auto3[0x1c]; + uint32_t gtpu_teid; + uint32_t gtpu_msg_type:8; + uint32_t gtpu_flags:3; }; struct dr_match_param {