Commit 784feaa6 authored by Marcin Szycik's avatar Marcin Szycik Committed by David S. Miller
Browse files

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: default avatarMarcin Szycik <marcin.szycik@linux.intel.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarAlexander Lobakin <aleksander.lobakin@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2312dfdf
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -721,6 +721,12 @@ static bool ice_is_gtp_c_profile(u16 prof_idx)
	}
}

static bool ice_is_pfcp_profile(u16 prof_idx)
{
	return prof_idx >= ICE_PROFID_IPV4_PFCP_NODE &&
	       prof_idx <= ICE_PROFID_IPV6_PFCP_SESSION;
}

/**
 * ice_get_sw_prof_type - determine switch profile type
 * @hw: pointer to the HW structure
@@ -738,6 +744,9 @@ static enum ice_prof_type ice_get_sw_prof_type(struct ice_hw *hw,
	if (ice_is_gtp_u_profile(prof_idx))
		return ICE_PROF_TUN_GTPU;

	if (ice_is_pfcp_profile(prof_idx))
		return ICE_PROF_TUN_PFCP;

	for (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) {
		/* UDP tunnel will have UDP_OF protocol ID and VNI offset */
		if (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF &&
+3 −1
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ enum ice_tunnel_type {
	TNL_GRETAP,
	TNL_GTPC,
	TNL_GTPU,
	TNL_PFCP,
	__TNL_TYPE_CNT,
	TNL_LAST = 0xFF,
	TNL_ALL = 0xFF,
@@ -358,7 +359,8 @@ enum ice_prof_type {
	ICE_PROF_TUN_GRE = 0x4,
	ICE_PROF_TUN_GTPU = 0x8,
	ICE_PROF_TUN_GTPC = 0x10,
	ICE_PROF_TUN_ALL = 0x1E,
	ICE_PROF_TUN_PFCP = 0x20,
	ICE_PROF_TUN_ALL = 0x3E,
	ICE_PROF_ALL = 0xFF,
};

+12 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ enum ice_protocol_type {
	ICE_NVGRE,
	ICE_GTP,
	ICE_GTP_NO_PAY,
	ICE_PFCP,
	ICE_PPPOE,
	ICE_L2TPV3,
	ICE_VLAN_EX,
@@ -61,6 +62,7 @@ enum ice_sw_tunnel_type {
	ICE_SW_TUN_NVGRE,
	ICE_SW_TUN_GTPU,
	ICE_SW_TUN_GTPC,
	ICE_SW_TUN_PFCP,
	ICE_ALL_TUNNELS /* All tunnel types including NVGRE */
};

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

struct ice_pfcp_hdr {
	u8 flags;
	u8 msg_type;
	__be16 length;
	__be64 seid;
	__be32 seq;
	u8 spare;
} __packed __aligned(__alignof__(u16));

struct ice_pppoe_hdr {
	u8 rsrvd_ver_type;
	u8 rsrvd_code;
@@ -418,6 +429,7 @@ union ice_prot_hdr {
	struct ice_udp_tnl_hdr tnl_hdr;
	struct ice_nvgre_hdr nvgre_hdr;
	struct ice_udp_gtp_hdr gtp_hdr;
	struct ice_pfcp_hdr pfcp_hdr;
	struct ice_pppoe_hdr pppoe_hdr;
	struct ice_l2tpv3_sess_hdr l2tpv3_sess_hdr;
	struct ice_hw_metadata metadata;
+85 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ enum {
	ICE_PKT_KMALLOC		= BIT(9),
	ICE_PKT_PPPOE		= BIT(10),
	ICE_PKT_L2TPV3		= BIT(11),
	ICE_PKT_PFCP		= BIT(12),
};

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

ICE_DECLARE_PKT_OFFSETS(pfcp_session_ipv4) = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_ETYPE_OL,		12 },
	{ ICE_IPV4_OFOS,	14 },
	{ ICE_UDP_ILOS,		34 },
	{ ICE_PFCP,		42 },
	{ ICE_PROTOCOL_LAST,	0 },
};

ICE_DECLARE_PKT_TEMPLATE(pfcp_session_ipv4) = {
	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x08, 0x00,		/* ICE_ETYPE_OL 12 */

	0x45, 0x00, 0x00, 0x2c, /* ICE_IPV4_OFOS 14 */
	0x00, 0x01, 0x00, 0x00,
	0x00, 0x11, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x22, 0x65, /* ICE_UDP_ILOS 34 */
	0x00, 0x18, 0x00, 0x00,

	0x21, 0x01, 0x00, 0x0c, /* ICE_PFCP 42 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00,		/* 2 bytes for 4 byte alignment */
};

ICE_DECLARE_PKT_OFFSETS(pfcp_session_ipv6) = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_ETYPE_OL,		12 },
	{ ICE_IPV6_OFOS,	14 },
	{ ICE_UDP_ILOS,		54 },
	{ ICE_PFCP,		62 },
	{ ICE_PROTOCOL_LAST,	0 },
};

ICE_DECLARE_PKT_TEMPLATE(pfcp_session_ipv6) = {
	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x86, 0xdd,		/* ICE_ETYPE_OL 12 */

	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
	0x00, 0x10, 0x11, 0x00, /* Next header UDP */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x22, 0x65, /* ICE_UDP_ILOS 54 */
	0x00, 0x18, 0x00, 0x00,

	0x21, 0x01, 0x00, 0x0c, /* ICE_PFCP 62 */
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	0x00, 0x00,		/* 2 bytes for 4 byte alignment */
};

ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_tcp) = {
	{ ICE_MAC_OFOS,		0 },
	{ ICE_ETYPE_OL,		12 },
@@ -1343,6 +1415,8 @@ static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = {
	ICE_PKT_PROFILE(ipv4_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU),
	ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPC | ICE_PKT_OUTER_IPV6),
	ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPC),
	ICE_PKT_PROFILE(pfcp_session_ipv6, ICE_PKT_PFCP | ICE_PKT_OUTER_IPV6),
	ICE_PKT_PROFILE(pfcp_session_ipv4, ICE_PKT_PFCP),
	ICE_PKT_PROFILE(pppoe_ipv6_udp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6 |
					ICE_PKT_INNER_UDP),
	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] = {
	ICE_PROTOCOL_ENTRY(ICE_NVGRE, 0, 2, 4, 6),
	ICE_PROTOCOL_ENTRY(ICE_GTP, 8, 10, 12, 14, 16, 18, 20, 22),
	ICE_PROTOCOL_ENTRY(ICE_GTP_NO_PAY, 8, 10, 12, 14),
	ICE_PROTOCOL_ENTRY(ICE_PFCP, 8, 10, 12, 14, 16, 18, 20, 22),
	ICE_PROTOCOL_ENTRY(ICE_PPPOE, 0, 2, 4, 6),
	ICE_PROTOCOL_ENTRY(ICE_L2TPV3, 0, 2, 4, 6, 8, 10),
	ICE_PROTOCOL_ENTRY(ICE_VLAN_EX, 2, 0),
@@ -4565,6 +4640,7 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
	{ ICE_NVGRE,		ICE_GRE_OF_HW },
	{ ICE_GTP,		ICE_UDP_OF_HW },
	{ ICE_GTP_NO_PAY,	ICE_UDP_ILOS_HW },
	{ ICE_PFCP,		ICE_UDP_ILOS_HW },
	{ ICE_PPPOE,		ICE_PPPOE_HW },
	{ ICE_L2TPV3,		ICE_L2TPV3_HW },
	{ 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,
	case ICE_SW_TUN_GTPC:
		prof_type = ICE_PROF_TUN_GTPC;
		break;
	case ICE_SW_TUN_PFCP:
		prof_type = ICE_PROF_TUN_PFCP;
		break;
	case ICE_SW_TUN_AND_NON_TUN:
	default:
		prof_type = ICE_PROF_ALL;
@@ -5556,6 +5635,9 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
	case ICE_SW_TUN_VXLAN:
		match |= ICE_PKT_TUN_UDP;
		break;
	case ICE_SW_TUN_PFCP:
		match |= ICE_PKT_PFCP;
		break;
	default:
		break;
	}
@@ -5696,6 +5778,9 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
		case ICE_GTP:
			len = sizeof(struct ice_udp_gtp_hdr);
			break;
		case ICE_PFCP:
			len = sizeof(struct ice_pfcp_hdr);
			break;
		case ICE_PPPOE:
			len = sizeof(struct ice_pppoe_hdr);
			break;
+2 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#define ICE_PROFID_IPV6_GTPC_NO_TEID			45
#define ICE_PROFID_IPV6_GTPU_TEID			46
#define ICE_PROFID_IPV6_GTPU_IPV6_TCP_INNER		70
#define ICE_PROFID_IPV4_PFCP_NODE			79
#define ICE_PROFID_IPV6_PFCP_SESSION			82

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