# PFCP

Packet Forwarding Control Protocol (PFCP) is a 3GPP protocol used on the Sx/N4 interface between the control plane and the user plane function, specified in TS 29.244. It is one of the main protocols introduced in the 5G Next Generation Mobile Core Network (aka 5GC), but also used in the 4G/LTE EPC to implement the Control and User Plane Separation (CUPS). PFCP and the associated interfaces seek to formalize the interactions between different types of functional elements used in the Mobile Core Networks as deployed by most operators providing 4G, as well as 5G, services to mobile subscribers. These two types of components are:
* The Control Plane (CP) functional elements, handling mostly signaling procedures (e.g. network attachment procedures, management of User-data Plane paths and even delivery of some light-weight services as SMS)
* The User-data Plane (UP) functional elements, handling mostly packet forwarding, based on rules set by the CP elements (e.g. packet forwarding for IPv4, IPv6 - or possibly even Ethernet with future 5G deployments - between the various supported wireless RANs and the PDN representing the Internet or an enterprise network).
PFCP's scope is similar to that of OpenFlow, however it was engineered to serve the particular use-case of Mobile Core Networks.
PFCP is also used on the interface between the control plane and user plane functions of a disaggregated BNG, as defined by the BroadBand Forum in TR-459.

## Overview

Albeit similar to GTP in concepts and implementation, PFCP is complementary to it. It provides the control means for a signaling component of the Control-Plane to manage packet processing and forwarding performed by a User-Plane component. Typical EPC or 5G Packet Gateways are split by the protocol in two functional parts, allowing for a more natural evolution and scalability.
The PFCP protocol is used on the following 3GPP mobile core interfaces:
* Sxa - between SGW-C and SGW-U
* Sxb - between PGW-C and PGW-U
* Sxc - between TDF-C and TDF-U (Traffic Detection Function)
* N4 - between SMF and UPF
Note: Sxa and Sxb can be combined, in case a merged SGW/PGW is implemented.

## Functionality

The Control-Plane functional element (e.g. PGW-C, SMF) controls the packet processing and forwarding in the User-Plane functional elements (e.g. PGW-U, UPF), by establishing, modifying or deleting PFCP Sessions.
User plane packets shall be forwarded between the CP and UP functions by encapsulating the user plane packets using GTP-U encapsulation (see 3GPP TS 29.281 [3]). For forwarding data from the UP function to the CP function, the CP function shall provision Packet Detection Rules (PDR) per PFCP session context, with the Packet Detection Information (PDI) identifying the user plane traffic to forward to the CP function and with a Forwarding Action Rule (FAR) set with the Destination Interface "CP function side" and set to perform GTP-U encapsulation and to forward the packets to a GTP-u F-TEID uniquely assigned in the CP function per PFCP session and PDR. The CP function shall then identify the PDN connection and the bearer to which the forwarded data belongs by the Fully Qualified TEID (F-TEID) in the header of the encapsulating GTP-U packet. For forwarding data from the CP function to the UP function, the CP function shall provision one or more PDR(s) per PFCP session context, with the PDI set with the Source Interface "CP function side" and identifying the GTP-u F-TEID uniquely assigned in the UP function per PDR, and with a FAR set to perform GTP-U decapsulation and to forward the packets to the intended destination. URRs and QERs may also be configured.
Per session multiple PDRs, FARs, QoS Enforcement Rules (QER), Usage Reporting Rules (URR) and/or Buffering Action Rules (BAR) are sent.
Here are the main concepts used, organized in their logical association model:
* PDRs - Packet Detection Rules - contain information for matching data packets to certain processing rules. Both outer encapsulation and inner user-plane headers can be matched. The following rules can be applied on positive matching:
** FARs - Forwarding Action Rules - whether and how the packets matching PDRs should be dropped, forwarded, buffered or duplicated, including a trigger for first packet notification; it includes packet encapsulation or header enrichment rules. In case of buffering, the following rules can be applied:
*** BARs - Buffering Action Rules - how much data to buffer and how to notify the Control-Plane.
** QERs - QoS Enforcement Rules - rules for providing Gating and QoS Control, flow and service level marking.
** URRs - Usage Reporting Rules - contain rules for counting and reporting traffic handled by the User-Plane function, generating reports to enable charging functionality in the Control-Plane functions.

## Messages

PFCP Message Format :
| Bit/Byte offset | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
| Bytes 0..3 | Version (1) | Version (1) | Version (1) | (spare 0s) | (spare 0s) | FO | MP | S | Message Type | Message Type | Message Type | Message Type | Message Type | Message Type | Message Type | Message Type | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) | Message Length (in bytes, not including the first 4) |
| Bytes 4..11 | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing |
| Bytes 8..11 | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing | if (S flag set) then SEID; else these bytes are missing |
| Bytes 4..7 or 12..15 | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | Sequence Number | if (MP flag set) then Message Priority; else (spare 0s) | if (MP flag set) then Message Priority; else (spare 0s) | if (MP flag set) then Message Priority; else (spare 0s) | if (MP flag set) then Message Priority; else (spare 0s) | (spare 0s) | (spare 0s) | (spare 0s) | (spare 0s) |
| Bytes 8..(MsgLen+4) or 16..(MsgLen+4) | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements | Zero or more Information Elements |
PFCP Information Element Format :
| Bit/Byte offset | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
| Bytes 0..3 | Type | Type | Type | Type | Type | Type | Type | Type | Type | Type | Type | Type | Type | Type | Type | Type | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) | IE Length (in bytes, not including the first 4) |
| Bytes 4..IELen+4 | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | if (Type >= 32768) then Enterprise-ID; else this is part of the Payload | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... | Payload (cont.) ... |
| Payload cont. ... ||||||||||||||||||||||||||||||||
IEs are defined either as having a proprietary encoding, or as grouped. Grouped IEs are simply a list of other IEs, encoded one after the other like in the PFCP Message Payload.
IE Types 0..32767 are 3GPP specific and do not have an Enterprise-ID set. IE Types 32768..65535 can be used by custom implementation and the Enterprise-ID must be set to the IANA SMI Network Management Private Enterprise Codes of the issuing party.

## Messages

Standardized Message Types :
| Message Type | Message Type | Message | Interface Applicability | Interface Applicability | Interface Applicability | Interface Applicability | Direction | Direction | Purpose |
| Request | Response | Message | Sxa | Sxb | Sxc | N4 | Request | Response | Purpose |
| 0 | 0 | (Reserved) | (Reserved) | (Reserved) | (Reserved) | (Reserved) | (Reserved) | (Reserved) | |
| (1..49) | (1..49) | Node Related Messages | Node Related Messages | Node Related Messages | Node Related Messages | Node Related Messages | Node Related Messages | Node Related Messages | |
| 1 | 2 | Heartbeat | X | X | X | X | CP ↔ UP | CP ↔ UP | Can be optionally used between communication peers which have an established association, to check if the other node is alive. A Recovery-Timestamp is used to detect if the other peer has been restarted. |
| 3 | 4 | PFD Management | - | X | X | X | CP → UP | UP → CP | Optional feature, to provision PFDs per Application identifier, outside of the regular PFCP sessions. |
| 5 | 6 | Association Setup | X | X | X | X | CP ↔ UP | CP ↔ UP | Setup and update an association between CP and UP functional elements. Includes list of optional features, to inform the other elements about capabilities; other configuration elements are passed as well. No session related messages should be exchanged before this procedure. While the Association-Release is only triggered by the CP, the UP can request it as part of the Association-Update-Request. |
| 7 | 8 | Association Update | X | X | X | X | CP ↔ UP | CP ↔ UP | | Setup and update an association between CP and UP functional elements. Includes list of optional features, to inform the other elements about capabilities; other configuration elements are passed as well. No session related messages should be exchanged before this procedure. While the Association-Release is only triggered by the CP, the UP can request it as part of the Association-Update-Request. |
| 9 | 10 | Association Release | X | X | X | X | CP → UP | UP → CP | Setup and update an association between CP and UP functional elements. Includes list of optional features, to inform the other elements about capabilities; other configuration elements are passed as well. No session related messages should be exchanged before this procedure. While the Association-Release is only triggered by the CP, the UP can request it as part of the Association-Update-Request. |
| - | 11 | Version Not Supported | X | X | X | X | | CP ↔ UP | Error response to all requests which do not cover the implemented versions (currently only version 1 defined). |
| 12 | 13 | Node Report | X | X | X | X | UP → CP | CP → UP | Sent by the UP function to report information which is not part of a session, but potentially general (e.g. user-plane path failure). |
| 14 | 15 | Session Set Deletion | X | X | - | | CP → UP | UP → CP | Sent by the CP function to indicate a partial failure, requesting deletion of all sessions affected. |
| (50..99) | (50..99) | Session Related Messages | Session Related Messages | Session Related Messages | Session Related Messages | Session Related Messages | Session Related Messages | Session Related Messages | |
| 50 | 51 | Session Establishment | X | X | X | X | CP → UP | UP → CP | Used by the CP to set up, modify and remove sessions consisting of sets of rules for processing and forwarding UP traffic. These are the main functional message of the PFCP application domain. The UP may include Usage Report information in the answer, such that an additional Session-Report message would be avoided. |
| 52 | 53 | Session Modification | X | X | X | X | CP → UP | UP → CP | Used by the CP to set up, modify and remove sessions consisting of sets of rules for processing and forwarding UP traffic. These are the main functional message of the PFCP application domain. The UP may include Usage Report information in the answer, such that an additional Session-Report message would be avoided. |
| 54 | 55 | Session Deletion | X | X | X | X | CP → UP | UP → CP | Used by the CP to set up, modify and remove sessions consisting of sets of rules for processing and forwarding UP traffic. These are the main functional message of the PFCP application domain. The UP may include Usage Report information in the answer, such that an additional Session-Report message would be avoided. |
| 56 | 57 | Session Report | X | X | X | X | UP → CP | CP → UP | Report from UP Usage Report information based on the packet processing and forwarding procedures: downlink data (notification of new packets queued), usage report (volume, time, etc based information, for charging purposes), errors and/or inactivity indications. |
| (100..255) | (100..255) | Other Messages | Other Messages | Other Messages | Other Messages | Other Messages | Other Messages | Other Messages | |

## Transport

Very similar to GTP-C, PFCP uses UDP. Port 8805 is reserved.
For reliability, a similar re-transmission strategy as for GTP-C is employed, lost messages being sent N1-times at T1-intervals. Transactions are identified by the 3-byte long Sequence Number, the IP address and port of the communication peer.
The protocol includes an own Heart-beat Request/Response model, which allows monitoring the availability of communication peers and detecting restarts (by use of a Recovery-Timestamp Information Element).
For User-Plane packet exchanges between the Control and User Plane functional elements, GTP-U for the Sx-u interface, or alternatively a simpler UDP or Ethernet encapsulation for the N4-u interface (to be confirmed, as standards are still incomplete).