Skip to content

Commit 784feaa

Browse files
Marcin Szycikdavem330
authored andcommitted
ice: Add support for PFCP hardware offload in switchdev
Add support for creating PFCP filters in switchdev mode. Add support for parsing PFCP-specific tc options: S flag and SEID. To create a PFCP filter, a special netdev must be created and passed to tc command: ip link add pfcp0 type pfcp tc filter add dev eth0 ingress prio 1 flower pfcp_opts \ 1:123/ff:fffffffffffffff0 skip_hw action mirred egress redirect \ dev pfcp0 Changes in iproute2 [1] are required to be able to use pfcp_opts in tc. ICE COMMS package is required to create a filter as it contains PFCP profiles. Link: https://lore.kernel.org/netdev/20230614091758.11180-1-marcin.szycik@linux.intel.com [1] Signed-off-by: Marcin Szycik <marcin.szycik@linux.intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2312dfd commit 784feaa

File tree

7 files changed

+169
-7
lines changed

7 files changed

+169
-7
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,12 @@ static bool ice_is_gtp_c_profile(u16 prof_idx)
721721
}
722722
}
723723

724+
static bool ice_is_pfcp_profile(u16 prof_idx)
725+
{
726+
return prof_idx >= ICE_PROFID_IPV4_PFCP_NODE &&
727+
prof_idx <= ICE_PROFID_IPV6_PFCP_SESSION;
728+
}
729+
724730
/**
725731
* ice_get_sw_prof_type - determine switch profile type
726732
* @hw: pointer to the HW structure
@@ -738,6 +744,9 @@ static enum ice_prof_type ice_get_sw_prof_type(struct ice_hw *hw,
738744
if (ice_is_gtp_u_profile(prof_idx))
739745
return ICE_PROF_TUN_GTPU;
740746

747+
if (ice_is_pfcp_profile(prof_idx))
748+
return ICE_PROF_TUN_PFCP;
749+
741750
for (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) {
742751
/* UDP tunnel will have UDP_OF protocol ID and VNI offset */
743752
if (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF &&

drivers/net/ethernet/intel/ice/ice_flex_type.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ enum ice_tunnel_type {
9393
TNL_GRETAP,
9494
TNL_GTPC,
9595
TNL_GTPU,
96+
TNL_PFCP,
9697
__TNL_TYPE_CNT,
9798
TNL_LAST = 0xFF,
9899
TNL_ALL = 0xFF,
@@ -358,7 +359,8 @@ enum ice_prof_type {
358359
ICE_PROF_TUN_GRE = 0x4,
359360
ICE_PROF_TUN_GTPU = 0x8,
360361
ICE_PROF_TUN_GTPC = 0x10,
361-
ICE_PROF_TUN_ALL = 0x1E,
362+
ICE_PROF_TUN_PFCP = 0x20,
363+
ICE_PROF_TUN_ALL = 0x3E,
362364
ICE_PROF_ALL = 0xFF,
363365
};
364366

drivers/net/ethernet/intel/ice/ice_protocol_type.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum ice_protocol_type {
4343
ICE_NVGRE,
4444
ICE_GTP,
4545
ICE_GTP_NO_PAY,
46+
ICE_PFCP,
4647
ICE_PPPOE,
4748
ICE_L2TPV3,
4849
ICE_VLAN_EX,
@@ -61,6 +62,7 @@ enum ice_sw_tunnel_type {
6162
ICE_SW_TUN_NVGRE,
6263
ICE_SW_TUN_GTPU,
6364
ICE_SW_TUN_GTPC,
65+
ICE_SW_TUN_PFCP,
6466
ICE_ALL_TUNNELS /* All tunnel types including NVGRE */
6567
};
6668

@@ -202,6 +204,15 @@ struct ice_udp_gtp_hdr {
202204
u8 rsvrd;
203205
};
204206

207+
struct ice_pfcp_hdr {
208+
u8 flags;
209+
u8 msg_type;
210+
__be16 length;
211+
__be64 seid;
212+
__be32 seq;
213+
u8 spare;
214+
} __packed __aligned(__alignof__(u16));
215+
205216
struct ice_pppoe_hdr {
206217
u8 rsrvd_ver_type;
207218
u8 rsrvd_code;
@@ -418,6 +429,7 @@ union ice_prot_hdr {
418429
struct ice_udp_tnl_hdr tnl_hdr;
419430
struct ice_nvgre_hdr nvgre_hdr;
420431
struct ice_udp_gtp_hdr gtp_hdr;
432+
struct ice_pfcp_hdr pfcp_hdr;
421433
struct ice_pppoe_hdr pppoe_hdr;
422434
struct ice_l2tpv3_sess_hdr l2tpv3_sess_hdr;
423435
struct ice_hw_metadata metadata;

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

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ enum {
4242
ICE_PKT_KMALLOC = BIT(9),
4343
ICE_PKT_PPPOE = BIT(10),
4444
ICE_PKT_L2TPV3 = BIT(11),
45+
ICE_PKT_PFCP = BIT(12),
4546
};
4647

4748
struct ice_dummy_pkt_offsets {
@@ -1110,6 +1111,77 @@ ICE_DECLARE_PKT_TEMPLATE(ipv6_gtp) = {
11101111
0x00, 0x00,
11111112
};
11121113

1114+
ICE_DECLARE_PKT_OFFSETS(pfcp_session_ipv4) = {
1115+
{ ICE_MAC_OFOS, 0 },
1116+
{ ICE_ETYPE_OL, 12 },
1117+
{ ICE_IPV4_OFOS, 14 },
1118+
{ ICE_UDP_ILOS, 34 },
1119+
{ ICE_PFCP, 42 },
1120+
{ ICE_PROTOCOL_LAST, 0 },
1121+
};
1122+
1123+
ICE_DECLARE_PKT_TEMPLATE(pfcp_session_ipv4) = {
1124+
0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1125+
0x00, 0x00, 0x00, 0x00,
1126+
0x00, 0x00, 0x00, 0x00,
1127+
1128+
0x08, 0x00, /* ICE_ETYPE_OL 12 */
1129+
1130+
0x45, 0x00, 0x00, 0x2c, /* ICE_IPV4_OFOS 14 */
1131+
0x00, 0x01, 0x00, 0x00,
1132+
0x00, 0x11, 0x00, 0x00,
1133+
0x00, 0x00, 0x00, 0x00,
1134+
0x00, 0x00, 0x00, 0x00,
1135+
1136+
0x00, 0x00, 0x22, 0x65, /* ICE_UDP_ILOS 34 */
1137+
0x00, 0x18, 0x00, 0x00,
1138+
1139+
0x21, 0x01, 0x00, 0x0c, /* ICE_PFCP 42 */
1140+
0x00, 0x00, 0x00, 0x00,
1141+
0x00, 0x00, 0x00, 0x00,
1142+
0x00, 0x00, 0x00, 0x00,
1143+
1144+
0x00, 0x00, /* 2 bytes for 4 byte alignment */
1145+
};
1146+
1147+
ICE_DECLARE_PKT_OFFSETS(pfcp_session_ipv6) = {
1148+
{ ICE_MAC_OFOS, 0 },
1149+
{ ICE_ETYPE_OL, 12 },
1150+
{ ICE_IPV6_OFOS, 14 },
1151+
{ ICE_UDP_ILOS, 54 },
1152+
{ ICE_PFCP, 62 },
1153+
{ ICE_PROTOCOL_LAST, 0 },
1154+
};
1155+
1156+
ICE_DECLARE_PKT_TEMPLATE(pfcp_session_ipv6) = {
1157+
0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1158+
0x00, 0x00, 0x00, 0x00,
1159+
0x00, 0x00, 0x00, 0x00,
1160+
1161+
0x86, 0xdd, /* ICE_ETYPE_OL 12 */
1162+
1163+
0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1164+
0x00, 0x10, 0x11, 0x00, /* Next header UDP */
1165+
0x00, 0x00, 0x00, 0x00,
1166+
0x00, 0x00, 0x00, 0x00,
1167+
0x00, 0x00, 0x00, 0x00,
1168+
0x00, 0x00, 0x00, 0x00,
1169+
0x00, 0x00, 0x00, 0x00,
1170+
0x00, 0x00, 0x00, 0x00,
1171+
0x00, 0x00, 0x00, 0x00,
1172+
0x00, 0x00, 0x00, 0x00,
1173+
1174+
0x00, 0x00, 0x22, 0x65, /* ICE_UDP_ILOS 54 */
1175+
0x00, 0x18, 0x00, 0x00,
1176+
1177+
0x21, 0x01, 0x00, 0x0c, /* ICE_PFCP 62 */
1178+
0x00, 0x00, 0x00, 0x00,
1179+
0x00, 0x00, 0x00, 0x00,
1180+
0x00, 0x00, 0x00, 0x00,
1181+
1182+
0x00, 0x00, /* 2 bytes for 4 byte alignment */
1183+
};
1184+
11131185
ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_tcp) = {
11141186
{ ICE_MAC_OFOS, 0 },
11151187
{ ICE_ETYPE_OL, 12 },
@@ -1343,6 +1415,8 @@ static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = {
13431415
ICE_PKT_PROFILE(ipv4_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU),
13441416
ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPC | ICE_PKT_OUTER_IPV6),
13451417
ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPC),
1418+
ICE_PKT_PROFILE(pfcp_session_ipv6, ICE_PKT_PFCP | ICE_PKT_OUTER_IPV6),
1419+
ICE_PKT_PROFILE(pfcp_session_ipv4, ICE_PKT_PFCP),
13461420
ICE_PKT_PROFILE(pppoe_ipv6_udp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6 |
13471421
ICE_PKT_INNER_UDP),
13481422
ICE_PKT_PROFILE(pppoe_ipv6_tcp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6),
@@ -4532,6 +4606,7 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
45324606
ICE_PROTOCOL_ENTRY(ICE_NVGRE, 0, 2, 4, 6),
45334607
ICE_PROTOCOL_ENTRY(ICE_GTP, 8, 10, 12, 14, 16, 18, 20, 22),
45344608
ICE_PROTOCOL_ENTRY(ICE_GTP_NO_PAY, 8, 10, 12, 14),
4609+
ICE_PROTOCOL_ENTRY(ICE_PFCP, 8, 10, 12, 14, 16, 18, 20, 22),
45354610
ICE_PROTOCOL_ENTRY(ICE_PPPOE, 0, 2, 4, 6),
45364611
ICE_PROTOCOL_ENTRY(ICE_L2TPV3, 0, 2, 4, 6, 8, 10),
45374612
ICE_PROTOCOL_ENTRY(ICE_VLAN_EX, 2, 0),
@@ -4565,6 +4640,7 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
45654640
{ ICE_NVGRE, ICE_GRE_OF_HW },
45664641
{ ICE_GTP, ICE_UDP_OF_HW },
45674642
{ ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW },
4643+
{ ICE_PFCP, ICE_UDP_ILOS_HW },
45684644
{ ICE_PPPOE, ICE_PPPOE_HW },
45694645
{ ICE_L2TPV3, ICE_L2TPV3_HW },
45704646
{ ICE_VLAN_EX, ICE_VLAN_OF_HW },
@@ -5272,6 +5348,9 @@ ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
52725348
case ICE_SW_TUN_GTPC:
52735349
prof_type = ICE_PROF_TUN_GTPC;
52745350
break;
5351+
case ICE_SW_TUN_PFCP:
5352+
prof_type = ICE_PROF_TUN_PFCP;
5353+
break;
52755354
case ICE_SW_TUN_AND_NON_TUN:
52765355
default:
52775356
prof_type = ICE_PROF_ALL;
@@ -5556,6 +5635,9 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
55565635
case ICE_SW_TUN_VXLAN:
55575636
match |= ICE_PKT_TUN_UDP;
55585637
break;
5638+
case ICE_SW_TUN_PFCP:
5639+
match |= ICE_PKT_PFCP;
5640+
break;
55595641
default:
55605642
break;
55615643
}
@@ -5696,6 +5778,9 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
56965778
case ICE_GTP:
56975779
len = sizeof(struct ice_udp_gtp_hdr);
56985780
break;
5781+
case ICE_PFCP:
5782+
len = sizeof(struct ice_pfcp_hdr);
5783+
break;
56995784
case ICE_PPPOE:
57005785
len = sizeof(struct ice_pppoe_hdr);
57015786
break;

drivers/net/ethernet/intel/ice/ice_switch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#define ICE_PROFID_IPV6_GTPC_NO_TEID 45
2323
#define ICE_PROFID_IPV6_GTPU_TEID 46
2424
#define ICE_PROFID_IPV6_GTPU_IPV6_TCP_INNER 70
25+
#define ICE_PROFID_IPV4_PFCP_NODE 79
26+
#define ICE_PROFID_IPV6_PFCP_SESSION 82
2527

2628
#define ICE_SW_RULE_VSI_LIST_SIZE(s, n) struct_size((s), vsi, (n))
2729
#define ICE_SW_RULE_RX_TX_HDR_SIZE(s, l) struct_size((s), hdr_data, (l))

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

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
3838
if (flags & ICE_TC_FLWR_FIELD_GTP_OPTS)
3939
lkups_cnt++;
4040

41+
if (flags & ICE_TC_FLWR_FIELD_PFCP_OPTS)
42+
lkups_cnt++;
43+
4144
if (flags & (ICE_TC_FLWR_FIELD_ENC_SRC_IPV4 |
4245
ICE_TC_FLWR_FIELD_ENC_DEST_IPV4 |
4346
ICE_TC_FLWR_FIELD_ENC_SRC_IPV6 |
@@ -138,6 +141,8 @@ ice_proto_type_from_tunnel(enum ice_tunnel_type type)
138141
return ICE_GTP;
139142
case TNL_GTPC:
140143
return ICE_GTP_NO_PAY;
144+
case TNL_PFCP:
145+
return ICE_PFCP;
141146
default:
142147
return 0;
143148
}
@@ -157,6 +162,8 @@ ice_sw_type_from_tunnel(enum ice_tunnel_type type)
157162
return ICE_SW_TUN_GTPU;
158163
case TNL_GTPC:
159164
return ICE_SW_TUN_GTPC;
165+
case TNL_PFCP:
166+
return ICE_SW_TUN_PFCP;
160167
default:
161168
return ICE_NON_TUN;
162169
}
@@ -236,6 +243,22 @@ ice_tc_fill_tunnel_outer(u32 flags, struct ice_tc_flower_fltr *fltr,
236243
i++;
237244
}
238245

246+
if (flags & ICE_TC_FLWR_FIELD_PFCP_OPTS) {
247+
struct ice_pfcp_hdr *hdr_h, *hdr_m;
248+
249+
hdr_h = &list[i].h_u.pfcp_hdr;
250+
hdr_m = &list[i].m_u.pfcp_hdr;
251+
list[i].type = ICE_PFCP;
252+
253+
hdr_h->flags = fltr->pfcp_meta_keys.type;
254+
hdr_m->flags = fltr->pfcp_meta_masks.type & 0x01;
255+
256+
hdr_h->seid = fltr->pfcp_meta_keys.seid;
257+
hdr_m->seid = fltr->pfcp_meta_masks.seid;
258+
259+
i++;
260+
}
261+
239262
if (flags & (ICE_TC_FLWR_FIELD_ENC_SRC_IPV4 |
240263
ICE_TC_FLWR_FIELD_ENC_DEST_IPV4)) {
241264
list[i].type = ice_proto_type_from_ipv4(false);
@@ -366,8 +389,11 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
366389
if (tc_fltr->tunnel_type != TNL_LAST) {
367390
i = ice_tc_fill_tunnel_outer(flags, tc_fltr, list, i);
368391

369-
headers = &tc_fltr->inner_headers;
370-
inner = true;
392+
/* PFCP is considered non-tunneled - don't swap headers. */
393+
if (tc_fltr->tunnel_type != TNL_PFCP) {
394+
headers = &tc_fltr->inner_headers;
395+
inner = true;
396+
}
371397
}
372398

373399
if (flags & ICE_TC_FLWR_FIELD_ETH_TYPE_ID) {
@@ -621,6 +647,8 @@ static int ice_tc_tun_get_type(struct net_device *tunnel_dev)
621647
*/
622648
if (netif_is_gtp(tunnel_dev))
623649
return TNL_GTPU;
650+
if (netif_is_pfcp(tunnel_dev))
651+
return TNL_PFCP;
624652
return TNL_LAST;
625653
}
626654

@@ -1415,6 +1443,20 @@ ice_parse_tunnel_attr(struct net_device *dev, struct flow_rule *rule,
14151443
fltr->flags |= ICE_TC_FLWR_FIELD_GTP_OPTS;
14161444
}
14171445

1446+
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_OPTS) &&
1447+
fltr->tunnel_type == TNL_PFCP) {
1448+
struct flow_match_enc_opts match;
1449+
1450+
flow_rule_match_enc_opts(rule, &match);
1451+
1452+
memcpy(&fltr->pfcp_meta_keys, match.key->data,
1453+
sizeof(struct pfcp_metadata));
1454+
memcpy(&fltr->pfcp_meta_masks, match.mask->data,
1455+
sizeof(struct pfcp_metadata));
1456+
1457+
fltr->flags |= ICE_TC_FLWR_FIELD_PFCP_OPTS;
1458+
}
1459+
14181460
return 0;
14191461
}
14201462

@@ -1473,10 +1515,14 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
14731515
return err;
14741516
}
14751517

1476-
/* header pointers should point to the inner headers, outer
1477-
* header were already set by ice_parse_tunnel_attr
1478-
*/
1479-
headers = &fltr->inner_headers;
1518+
/* PFCP is considered non-tunneled - don't swap headers. */
1519+
if (fltr->tunnel_type != TNL_PFCP) {
1520+
/* Header pointers should point to the inner headers,
1521+
* outer header were already set by
1522+
* ice_parse_tunnel_attr().
1523+
*/
1524+
headers = &fltr->inner_headers;
1525+
}
14801526
} else if (dissector->used_keys &
14811527
(BIT_ULL(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) |
14821528
BIT_ULL(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) |

drivers/net/ethernet/intel/ice/ice_tc_lib.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#ifndef _ICE_TC_LIB_H_
55
#define _ICE_TC_LIB_H_
66

7+
#include <linux/bits.h>
8+
#include <net/pfcp.h>
9+
710
#define ICE_TC_FLWR_FIELD_DST_MAC BIT(0)
811
#define ICE_TC_FLWR_FIELD_SRC_MAC BIT(1)
912
#define ICE_TC_FLWR_FIELD_VLAN BIT(2)
@@ -34,6 +37,7 @@
3437
#define ICE_TC_FLWR_FIELD_VLAN_PRIO BIT(27)
3538
#define ICE_TC_FLWR_FIELD_CVLAN_PRIO BIT(28)
3639
#define ICE_TC_FLWR_FIELD_VLAN_TPID BIT(29)
40+
#define ICE_TC_FLWR_FIELD_PFCP_OPTS BIT(30)
3741

3842
#define ICE_TC_FLOWER_MASK_32 0xFFFFFFFF
3943

@@ -161,6 +165,8 @@ struct ice_tc_flower_fltr {
161165
__be32 tenant_id;
162166
struct gtp_pdu_session_info gtp_pdu_info_keys;
163167
struct gtp_pdu_session_info gtp_pdu_info_masks;
168+
struct pfcp_metadata pfcp_meta_keys;
169+
struct pfcp_metadata pfcp_meta_masks;
164170
u32 flags;
165171
u8 tunnel_type;
166172
struct ice_tc_flower_action action;

0 commit comments

Comments
 (0)