Skip to content

Commit aa27cda

Browse files
committed
iavf: add RSS support for GTP protocol via ethtool
This patch extends the iavf driver to support Receive Side Scaling (RSS) configuration for GTP (GPRS Tunneling Protocol) flows using ethtool. The implementation introduces new RSS flow segment headers and hash field definitions for various GTP encapsulations, including: - GTPC - GTPU (IP, Extension Header, Uplink, Downlink) - TEID-based hashing The ethtool interface is updated to parse and apply these new flow types and hash fields, enabling fine-grained traffic distribution for GTP-based mobile workloads. This enhancement improves performance and scalability for virtualized network functions (VNFs) and user plane functions (UPFs) in 5G and LTE deployments. Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
1 parent 61baee2 commit aa27cda

4 files changed

Lines changed: 181 additions & 1 deletion

File tree

drivers/net/ethernet/intel/iavf/iavf_adv_rss.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,55 @@ iavf_fill_adv_rss_sctp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
9090
VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, DST_PORT);
9191
}
9292

93+
94+
/**
95+
* iavf_fill_adv_rss_gtp_hdr - Fill GTP-related RSS protocol headers
96+
* @proto_hdrs: pointer to the virtchnl protocol headers structure to populate
97+
* @packet_hdrs: bitmask of packet header types to configure
98+
* @hash_flds: RSS hash field configuration
99+
*
100+
* This function populates the virtchnl protocol header structure with
101+
* appropriate GTP-related header types based on the specified packet_hdrs.
102+
* It supports GTPC, GTPU with extension headers, and uplink/downlink PDU
103+
* types. For certain GTPU types, it also appends an IPv4 header to enable
104+
* hashing on the destination IP address.
105+
*
106+
* Return: 0 on success or -EINVAL if the packet_hdrs value is unsupported.
107+
*/
108+
static int
109+
iavf_fill_adv_rss_gtp_hdr(struct virtchnl_proto_hdrs *proto_hdrs, u32 packet_hdrs, u64 hash_flds)
110+
{
111+
struct virtchnl_proto_hdr *hdr;
112+
113+
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count - 1];
114+
switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP) {
115+
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID:
116+
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC:
117+
VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPC);
118+
break;
119+
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH:
120+
VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH);
121+
break;
122+
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP:
123+
VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_UP);
124+
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
125+
iavf_fill_adv_rss_ip4_hdr(hdr, IAVF_ADV_RSS_HASH_FLD_IPV4_DA);
126+
break;
127+
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN:
128+
VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_DWN);
129+
fallthrough;
130+
case IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP:
131+
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
132+
iavf_fill_adv_rss_ip4_hdr(hdr, IAVF_ADV_RSS_HASH_FLD_IPV4_DA);
133+
break;
134+
default:
135+
return -EINVAL;
136+
137+
}
138+
139+
return 0;
140+
}
141+
93142
/**
94143
* iavf_fill_adv_rss_cfg_msg - fill the RSS configuration into virtchnl message
95144
* @rss_cfg: the virtchnl message to be filled with RSS configuration setting
@@ -113,6 +162,7 @@ iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg,
113162

114163
proto_hdrs->tunnel_level = 0; /* always outer layer */
115164

165+
if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L3) {
116166
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
117167
switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L3) {
118168
case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4:
@@ -125,6 +175,9 @@ iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg,
125175
return -EINVAL;
126176
}
127177

178+
}
179+
180+
if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L4) {
128181
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
129182
switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L4) {
130183
case IAVF_ADV_RSS_FLOW_SEG_HDR_TCP:
@@ -140,6 +193,14 @@ iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg,
140193
return -EINVAL;
141194
}
142195

196+
}
197+
198+
if(packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP) {
199+
hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
200+
if (iavf_fill_adv_rss_gtp_hdr(proto_hdrs, packet_hdrs, hash_flds))
201+
return -EINVAL;
202+
}
203+
143204
return 0;
144205
}
145206

@@ -186,6 +247,8 @@ iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss,
186247
proto = "UDP";
187248
else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP)
188249
proto = "SCTP";
250+
else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_GTP)
251+
proto = "GTP";
189252
else
190253
return;
191254

@@ -211,6 +274,16 @@ iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss,
211274
IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT |
212275
IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT))
213276
strcat(hash_opt, "dst port,");
277+
if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_GTPC_TEID | IAVF_ADV_RSS_HASH_FLD_GTPC_TEID))
278+
strcat(hash_opt, "gtp-c,");
279+
if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_IP_TEID)
280+
strcat(hash_opt, "gtp-u ip,");
281+
if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_EH_TEID)
282+
strcat(hash_opt, "gtp-u ext,");
283+
if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_UP_TEID)
284+
strcat(hash_opt, "gtp-u ul,");
285+
if (hash_flds & IAVF_ADV_RSS_HASH_FLD_GTPU_DWN_TEID)
286+
strcat(hash_opt, "gtp-u dl,");
214287

215288
if (!action)
216289
action = "";

drivers/net/ethernet/intel/iavf/iavf_adv_rss.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ enum iavf_adv_rss_flow_seg_hdr {
2222
IAVF_ADV_RSS_FLOW_SEG_HDR_TCP = 0x00000004,
2323
IAVF_ADV_RSS_FLOW_SEG_HDR_UDP = 0x00000008,
2424
IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP = 0x00000010,
25+
/* RESERVED */
26+
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC = 0x00000400,
27+
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID = 0x00000800,
28+
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP = 0x00001000,
29+
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH = 0x00002000,
30+
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN = 0x00004000,
31+
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP = 0x00008000,
2532
};
2633

2734
#define IAVF_ADV_RSS_FLOW_SEG_HDR_L3 \
@@ -33,6 +40,14 @@ enum iavf_adv_rss_flow_seg_hdr {
3340
IAVF_ADV_RSS_FLOW_SEG_HDR_UDP | \
3441
IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP)
3542

43+
#define IAVF_ADV_RSS_FLOW_SEG_HDR_GTP \
44+
(IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC | \
45+
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID| \
46+
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP| \
47+
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH| \
48+
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN| \
49+
IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP)
50+
3651
enum iavf_adv_rss_flow_field {
3752
/* L3 */
3853
IAVF_ADV_RSS_FLOW_FIELD_IDX_IPV4_SA,
@@ -46,6 +61,17 @@ enum iavf_adv_rss_flow_field {
4661
IAVF_ADV_RSS_FLOW_FIELD_IDX_UDP_DST_PORT,
4762
IAVF_ADV_RSS_FLOW_FIELD_IDX_SCTP_SRC_PORT,
4863
IAVF_ADV_RSS_FLOW_FIELD_IDX_SCTP_DST_PORT,
64+
/* GTPC_TEID */
65+
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPC_TEID,
66+
/* GTPU_IP */
67+
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_IP_TEID,
68+
/* GTPU_EH */
69+
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_EH_TEID,
70+
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_EH_QFI,
71+
/* GTPU_UP */
72+
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_UP_TEID,
73+
/* GTPU_DWN */
74+
IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_DWN_TEID,
4975

5076
/* The total number of enums must not exceed 64 */
5177
IAVF_ADV_RSS_FLOW_FIELD_IDX_MAX
@@ -72,6 +98,12 @@ enum iavf_adv_rss_flow_field {
7298
BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_SCTP_SRC_PORT)
7399
#define IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT \
74100
BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_SCTP_DST_PORT)
101+
#define IAVF_ADV_RSS_HASH_FLD_GTPC_TEID BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPC_TEID)
102+
#define IAVF_ADV_RSS_HASH_FLD_GTPU_IP_TEID BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_IP_TEID)
103+
#define IAVF_ADV_RSS_HASH_FLD_GTPU_EH_TEID BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_EH_TEID)
104+
#define IAVF_ADV_RSS_HASH_FLD_GTPU_UP_TEID BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_UP_TEID)
105+
#define IAVF_ADV_RSS_HASH_FLD_GTPU_DWN_TEID \
106+
BIT_ULL(IAVF_ADV_RSS_FLOW_FIELD_IDX_GTPU_DWN_TEID)
75107

76108
/* bookkeeping of advanced RSS configuration */
77109
struct iavf_adv_rss {

drivers/net/ethernet/intel/iavf/iavf_ethtool.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,42 @@ static u32 iavf_adv_rss_parse_hdrs(struct ethtool_rxnfc *cmd)
13491349
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP |
13501350
IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
13511351
break;
1352+
case GTPU_V4_FLOW:
1353+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
1354+
break;
1355+
case GTPC_V4_FLOW:
1356+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC | IAVF_ADV_RSS_FLOW_SEG_HDR_UDP | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
1357+
break;
1358+
case GTPC_TEID_V4_FLOW:
1359+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID | IAVF_ADV_RSS_FLOW_SEG_HDR_UDP | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
1360+
break;
1361+
case GTPU_EH_V4_FLOW:
1362+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
1363+
break;
1364+
case GTPU_UL_V4_FLOW:
1365+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
1366+
break;
1367+
case GTPU_DL_V4_FLOW:
1368+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4;
1369+
break;
1370+
case GTPU_V6_FLOW:
1371+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_IP | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
1372+
break;
1373+
case GTPC_V6_FLOW:
1374+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
1375+
break;
1376+
case GTPC_TEID_V6_FLOW:
1377+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPC_TEID | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
1378+
break;
1379+
case GTPU_EH_V6_FLOW:
1380+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_EH | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
1381+
break;
1382+
case GTPU_UL_V6_FLOW:
1383+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_UP | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
1384+
break;
1385+
case GTPU_DL_V6_FLOW:
1386+
hdrs |= IAVF_ADV_RSS_FLOW_SEG_HDR_GTPU_DWN | IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6;
1387+
break;
13521388
default:
13531389
break;
13541390
}
@@ -1373,6 +1409,12 @@ static u64 iavf_adv_rss_parse_hash_flds(struct ethtool_rxnfc *cmd, bool symm)
13731409
case TCP_V4_FLOW:
13741410
case UDP_V4_FLOW:
13751411
case SCTP_V4_FLOW:
1412+
case GTPU_V4_FLOW:
1413+
case GTPC_V4_FLOW:
1414+
case GTPC_TEID_V4_FLOW:
1415+
case GTPU_EH_V4_FLOW:
1416+
case GTPU_UL_V4_FLOW:
1417+
case GTPU_DL_V4_FLOW:
13761418
if (cmd->data & RXH_IP_SRC)
13771419
hfld |= IAVF_ADV_RSS_HASH_FLD_IPV4_SA;
13781420
if (cmd->data & RXH_IP_DST)
@@ -1381,6 +1423,12 @@ static u64 iavf_adv_rss_parse_hash_flds(struct ethtool_rxnfc *cmd, bool symm)
13811423
case TCP_V6_FLOW:
13821424
case UDP_V6_FLOW:
13831425
case SCTP_V6_FLOW:
1426+
case GTPU_V6_FLOW:
1427+
case GTPC_V6_FLOW:
1428+
case GTPC_TEID_V6_FLOW:
1429+
case GTPU_EH_V6_FLOW:
1430+
case GTPU_UL_V6_FLOW:
1431+
case GTPU_DL_V6_FLOW:
13841432
if (cmd->data & RXH_IP_SRC)
13851433
hfld |= IAVF_ADV_RSS_HASH_FLD_IPV6_SA;
13861434
if (cmd->data & RXH_IP_DST)
@@ -1402,6 +1450,7 @@ static u64 iavf_adv_rss_parse_hash_flds(struct ethtool_rxnfc *cmd, bool symm)
14021450
break;
14031451
case UDP_V4_FLOW:
14041452
case UDP_V6_FLOW:
1453+
case GTPC_V4_FLOW:
14051454
if (cmd->data & RXH_L4_B_0_1)
14061455
hfld |= IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT;
14071456
if (cmd->data & RXH_L4_B_2_3)
@@ -1418,6 +1467,32 @@ static u64 iavf_adv_rss_parse_hash_flds(struct ethtool_rxnfc *cmd, bool symm)
14181467
break;
14191468
}
14201469
}
1470+
if (cmd->data & RXH_GTP_TEID) {
1471+
switch (cmd->flow_type) {
1472+
case GTPC_TEID_V4_FLOW:
1473+
case GTPC_TEID_V6_FLOW:
1474+
hfld |= IAVF_ADV_RSS_HASH_FLD_GTPC_TEID;
1475+
break;
1476+
case GTPU_V4_FLOW:
1477+
case GTPU_V6_FLOW:
1478+
hfld |= IAVF_ADV_RSS_HASH_FLD_GTPU_IP_TEID;
1479+
break;
1480+
case GTPU_EH_V4_FLOW:
1481+
case GTPU_EH_V6_FLOW:
1482+
hfld |= IAVF_ADV_RSS_HASH_FLD_GTPU_EH_TEID;
1483+
break;
1484+
case GTPU_UL_V4_FLOW:
1485+
case GTPU_UL_V6_FLOW:
1486+
hfld |= IAVF_ADV_RSS_HASH_FLD_GTPU_UP_TEID;
1487+
break;
1488+
case GTPU_DL_V4_FLOW:
1489+
case GTPU_DL_V6_FLOW:
1490+
hfld |= IAVF_ADV_RSS_HASH_FLD_GTPU_DWN_TEID;
1491+
break;
1492+
default:
1493+
break;
1494+
}
1495+
}
14211496

14221497
return hfld;
14231498
}

drivers/net/ethernet/intel/iavf/iavf_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ static int iavf_check_reset_complete(struct iavf_hw *hw);
2020

2121
char iavf_driver_name[] = "iavf";
2222
static const char iavf_driver_string[] =
23-
"Intel(R) Ethernet Adaptive Virtual Function Network Driver";
23+
"Intel(R) Ethernet Adaptive Virtual Function Network Driver +GTP-Uv16";
2424

2525
static const char iavf_copyright[] =
2626
"Copyright (c) 2013 - 2018 Intel Corporation.";

0 commit comments

Comments
 (0)