Skip to content

Commit 12ed3e5

Browse files
aloktionanguy11
authored andcommitted
ice: add flow parsing for GTP and new protocol field support
Introduce new protocol header types and field sizes to support GTPU, GTPC tunneling protocols. - Add field size macros for GTP TEID, QFI, and other headers - Extend ice_flow_field_info and enum definitions - Update hash macros for new protocols - Add support for IPv6 prefix matching and fragment headers This patch lays the groundwork for enhanced RSS and flow classification capabilities. Co-developed-by: Dan Nowlin <[email protected]> Signed-off-by: Dan Nowlin <[email protected]> Co-developed-by: Junfeng Guo <[email protected]> Signed-off-by: Junfeng Guo <[email protected]> Co-developed-by: Ting Xu <[email protected]> Signed-off-by: Ting Xu <[email protected]> Signed-off-by: Przemek Kitszel <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: Aleksandr Loktionov <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 2c031d4 commit 12ed3e5

File tree

3 files changed

+322
-9
lines changed

3 files changed

+322
-9
lines changed

drivers/net/ethernet/intel/ice/ice_flow.c

Lines changed: 212 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,38 @@
55
#include "ice_flow.h"
66
#include <net/gre.h>
77

8+
/* Size of known protocol header fields */
9+
#define ICE_FLOW_FLD_SZ_ETH_TYPE 2
10+
#define ICE_FLOW_FLD_SZ_VLAN 2
11+
#define ICE_FLOW_FLD_SZ_IPV4_ADDR 4
12+
#define ICE_FLOW_FLD_SZ_IPV6_ADDR 16
13+
#define ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR 4
14+
#define ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR 6
15+
#define ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR 8
16+
#define ICE_FLOW_FLD_SZ_IPV4_ID 2
17+
#define ICE_FLOW_FLD_SZ_IPV6_ID 4
18+
#define ICE_FLOW_FLD_SZ_IP_CHKSUM 2
19+
#define ICE_FLOW_FLD_SZ_TCP_CHKSUM 2
20+
#define ICE_FLOW_FLD_SZ_UDP_CHKSUM 2
21+
#define ICE_FLOW_FLD_SZ_SCTP_CHKSUM 4
22+
#define ICE_FLOW_FLD_SZ_IP_DSCP 1
23+
#define ICE_FLOW_FLD_SZ_IP_TTL 1
24+
#define ICE_FLOW_FLD_SZ_IP_PROT 1
25+
#define ICE_FLOW_FLD_SZ_PORT 2
26+
#define ICE_FLOW_FLD_SZ_TCP_FLAGS 1
27+
#define ICE_FLOW_FLD_SZ_ICMP_TYPE 1
28+
#define ICE_FLOW_FLD_SZ_ICMP_CODE 1
29+
#define ICE_FLOW_FLD_SZ_ARP_OPER 2
30+
#define ICE_FLOW_FLD_SZ_GRE_KEYID 4
31+
#define ICE_FLOW_FLD_SZ_GTP_TEID 4
32+
#define ICE_FLOW_FLD_SZ_GTP_QFI 2
33+
#define ICE_FLOW_FLD_SZ_PFCP_SEID 8
34+
#define ICE_FLOW_FLD_SZ_ESP_SPI 4
35+
#define ICE_FLOW_FLD_SZ_AH_SPI 4
36+
#define ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI 4
37+
#define ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID 2
38+
#define ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID 2
39+
840
/* Describe properties of a protocol header field */
941
struct ice_flow_field_info {
1042
enum ice_flow_seg_hdr hdr;
@@ -20,6 +52,7 @@ struct ice_flow_field_info {
2052
.mask = 0, \
2153
}
2254

55+
/* QFI: 6-bit field in GTP-U PDU Session Container (3GPP TS 38.415) */
2356
#define ICE_FLOW_FLD_INFO_MSK(_hdr, _offset_bytes, _size_bytes, _mask) { \
2457
.hdr = _hdr, \
2558
.off = (_offset_bytes) * BITS_PER_BYTE, \
@@ -61,7 +94,33 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
6194
/* ICE_FLOW_FIELD_IDX_IPV6_SA */
6295
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, sizeof(struct in6_addr)),
6396
/* ICE_FLOW_FIELD_IDX_IPV6_DA */
64-
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, sizeof(struct in6_addr)),
97+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, ICE_FLOW_FLD_SZ_IPV6_ADDR),
98+
/* ICE_FLOW_FIELD_IDX_IPV4_CHKSUM */
99+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 10, ICE_FLOW_FLD_SZ_IP_CHKSUM),
100+
/* ICE_FLOW_FIELD_IDX_IPV4_FRAG */
101+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4,
102+
ICE_FLOW_FLD_SZ_IPV4_ID),
103+
/* ICE_FLOW_FIELD_IDX_IPV6_FRAG */
104+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV_FRAG, 4,
105+
ICE_FLOW_FLD_SZ_IPV6_ID),
106+
/* ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA */
107+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
108+
ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR),
109+
/* ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA */
110+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
111+
ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR),
112+
/* ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA */
113+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
114+
ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR),
115+
/* ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA */
116+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
117+
ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR),
118+
/* ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA */
119+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8,
120+
ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR),
121+
/* ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA */
122+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24,
123+
ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR),
65124
/* Transport */
66125
/* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */
67126
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, sizeof(__be16)),
@@ -76,7 +135,14 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
76135
/* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */
77136
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 2, sizeof(__be16)),
78137
/* ICE_FLOW_FIELD_IDX_TCP_FLAGS */
79-
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, 1),
138+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 13, ICE_FLOW_FLD_SZ_TCP_FLAGS),
139+
/* ICE_FLOW_FIELD_IDX_TCP_CHKSUM */
140+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 16, ICE_FLOW_FLD_SZ_TCP_CHKSUM),
141+
/* ICE_FLOW_FIELD_IDX_UDP_CHKSUM */
142+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 6, ICE_FLOW_FLD_SZ_UDP_CHKSUM),
143+
/* ICE_FLOW_FIELD_IDX_SCTP_CHKSUM */
144+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_SCTP, 8,
145+
ICE_FLOW_FLD_SZ_SCTP_CHKSUM),
80146
/* ARP */
81147
/* ICE_FLOW_FIELD_IDX_ARP_SIP */
82148
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ARP, 14, sizeof(struct in_addr)),
@@ -108,9 +174,17 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
108174
ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_EH, 22, sizeof(__be16),
109175
0x3f00),
110176
/* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */
111-
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12, sizeof(__be32)),
177+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_UP, 12,
178+
ICE_FLOW_FLD_SZ_GTP_TEID),
179+
/* ICE_FLOW_FIELD_IDX_GTPU_UP_QFI */
180+
ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_UP, 22,
181+
ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00),
112182
/* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */
113-
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12, sizeof(__be32)),
183+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_GTPU_DWN, 12,
184+
ICE_FLOW_FLD_SZ_GTP_TEID),
185+
/* ICE_FLOW_FIELD_IDX_GTPU_DWN_QFI */
186+
ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_GTPU_DWN, 22,
187+
ICE_FLOW_FLD_SZ_GTP_QFI, 0x3f00),
114188
/* PPPoE */
115189
/* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
116190
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_PPPOE, 2, sizeof(__be16)),
@@ -128,7 +202,16 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
128202
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_AH, 4, sizeof(__be32)),
129203
/* NAT_T_ESP */
130204
/* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
131-
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8, sizeof(__be32)),
205+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NAT_T_ESP, 8,
206+
ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI),
207+
/* L2TPV2 */
208+
/* ICE_FLOW_FIELD_IDX_L2TPV2_SESS_ID */
209+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV2, 12,
210+
ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID),
211+
/* L2TPV2_LEN */
212+
/* ICE_FLOW_FIELD_IDX_L2TPV2_LEN_SESS_ID */
213+
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_L2TPV2, 14,
214+
ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID),
132215
};
133216

134217
/* Bitmaps indicating relevant packet types for a particular protocol header
@@ -2324,6 +2407,130 @@ static void ice_rss_set_symm(struct ice_hw *hw, struct ice_flow_prof *prof)
23242407
}
23252408
}
23262409

2410+
/**
2411+
* ice_rss_cfg_raw_symm - Configure symmetric RSS for a raw parser profile
2412+
* @hw: device HW
2413+
* @prof: parser profile describing extracted FV (field vector) entries
2414+
* @prof_id: RSS profile identifier used to program symmetry registers
2415+
*
2416+
* The routine scans the parser profile's FV entries and looks for
2417+
* direction-sensitive pairs (L3 src/dst, L4 src/dst). When a pair is found,
2418+
* it programs XOR-based symmetry so that flows hash identically regardless
2419+
* of packet direction. This preserves CPU affinity for the same 5-tuple.
2420+
*
2421+
* Notes:
2422+
* - The size of each logical field (IPv4/IPv6 address, L4 port) is expressed
2423+
* in units of ICE_FLOW_FV_EXTRACT_SZ so we can step across fv[] correctly.
2424+
* - We guard against out-of-bounds access before looking at fv[i + len].
2425+
*/
2426+
static void ice_rss_cfg_raw_symm(struct ice_hw *hw,
2427+
const struct ice_parser_profile *prof,
2428+
u64 prof_id)
2429+
{
2430+
for (size_t i = 0; i < prof->fv_num; i++) {
2431+
u8 proto_id = prof->fv[i].proto_id;
2432+
u16 src_off = 0, dst_off = 0;
2433+
size_t src_idx, dst_idx;
2434+
bool is_matched = false;
2435+
unsigned int len = 0;
2436+
2437+
switch (proto_id) {
2438+
/* IPv4 address pairs (outer/inner variants) */
2439+
case ICE_PROT_IPV4_OF_OR_S:
2440+
case ICE_PROT_IPV4_IL:
2441+
case ICE_PROT_IPV4_IL_IL:
2442+
len = ICE_FLOW_FLD_SZ_IPV4_ADDR /
2443+
ICE_FLOW_FV_EXTRACT_SZ;
2444+
src_off = ICE_FLOW_FIELD_IPV4_SRC_OFFSET;
2445+
dst_off = ICE_FLOW_FIELD_IPV4_DST_OFFSET;
2446+
break;
2447+
2448+
/* IPv6 address pairs (outer/inner variants) */
2449+
case ICE_PROT_IPV6_OF_OR_S:
2450+
case ICE_PROT_IPV6_IL:
2451+
case ICE_PROT_IPV6_IL_IL:
2452+
len = ICE_FLOW_FLD_SZ_IPV6_ADDR /
2453+
ICE_FLOW_FV_EXTRACT_SZ;
2454+
src_off = ICE_FLOW_FIELD_IPV6_SRC_OFFSET;
2455+
dst_off = ICE_FLOW_FIELD_IPV6_DST_OFFSET;
2456+
break;
2457+
2458+
/* L4 port pairs (TCP/UDP/SCTP) */
2459+
case ICE_PROT_TCP_IL:
2460+
case ICE_PROT_UDP_IL_OR_S:
2461+
case ICE_PROT_SCTP_IL:
2462+
len = ICE_FLOW_FLD_SZ_PORT / ICE_FLOW_FV_EXTRACT_SZ;
2463+
src_off = ICE_FLOW_FIELD_SRC_PORT_OFFSET;
2464+
dst_off = ICE_FLOW_FIELD_DST_PORT_OFFSET;
2465+
break;
2466+
2467+
default:
2468+
continue;
2469+
}
2470+
2471+
/* Bounds check before accessing fv[i + len]. */
2472+
if (i + len >= prof->fv_num)
2473+
continue;
2474+
2475+
/* Verify src/dst pairing for this protocol id. */
2476+
is_matched = prof->fv[i].offset == src_off &&
2477+
prof->fv[i + len].proto_id == proto_id &&
2478+
prof->fv[i + len].offset == dst_off;
2479+
if (!is_matched)
2480+
continue;
2481+
2482+
/* Program XOR symmetry for this field pair. */
2483+
src_idx = i;
2484+
dst_idx = i + len;
2485+
2486+
ice_rss_config_xor(hw, prof_id, src_idx, dst_idx, len);
2487+
2488+
/* Skip over the pair we just handled; the loop's ++i advances
2489+
* one more element, hence the --i after the jump.
2490+
*/
2491+
i += (2 * len);
2492+
/* not strictly needed; keeps static analyzers happy */
2493+
if (i == 0)
2494+
break;
2495+
--i;
2496+
}
2497+
}
2498+
2499+
/* Max registers index per packet profile */
2500+
#define ICE_SYMM_REG_INDEX_MAX 6
2501+
2502+
/**
2503+
* ice_rss_update_raw_symm - update symmetric hash configuration
2504+
* for raw pattern
2505+
* @hw: pointer to the hardware structure
2506+
* @cfg: configure parameters for raw pattern
2507+
* @id: profile tracking ID
2508+
*
2509+
* Update symmetric hash configuration for raw pattern if required.
2510+
* Otherwise only clear to default.
2511+
*/
2512+
void
2513+
ice_rss_update_raw_symm(struct ice_hw *hw,
2514+
struct ice_rss_raw_cfg *cfg, u64 id)
2515+
{
2516+
struct ice_prof_map *map;
2517+
u8 prof_id, m;
2518+
2519+
mutex_lock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
2520+
map = ice_search_prof_id(hw, ICE_BLK_RSS, id);
2521+
if (map)
2522+
prof_id = map->prof_id;
2523+
mutex_unlock(&hw->blk[ICE_BLK_RSS].es.prof_map_lock);
2524+
if (!map)
2525+
return;
2526+
/* clear to default */
2527+
for (m = 0; m < ICE_SYMM_REG_INDEX_MAX; m++)
2528+
wr32(hw, GLQF_HSYMM(prof_id, m), 0);
2529+
2530+
if (cfg->symm)
2531+
ice_rss_cfg_raw_symm(hw, &cfg->prof, prof_id);
2532+
}
2533+
23272534
/**
23282535
* ice_add_rss_cfg_sync - add an RSS configuration
23292536
* @hw: pointer to the hardware structure

0 commit comments

Comments
 (0)