Tag Archives: PFCP

PFCP and SIP Redirect

There’s a cool feature in PFCP that allows you to redirect traffic, which I’ve written about before.

But there’s a funky thing that’s left me scratching my head, in the Redirect information IE, you can set a SIP URI.

Snippet from TS 3GPP TS 29.244

That’d be great and all, but PFCP is all about packets not about calls.

So what’s the deal?

Had I uncovered some Machiavellian plot to move channel-associated-signaling onto PFCP instead of TDM links as God intended?

Well, no…

The Redirect Information in PFCP comes from the Redirect Information in Diameter, that’s how your OCS can tell your SMF or your PGW-C (or your TAS) – hey this session is all out of usage, and should be redirected.

Of course, PFCP is just all about packets, but Diameter has a foot in both camps, Gy and Ro are both on Diameter.

So when the 3GPP specced this IE, they just copied the encoding from the Redirect Address Type AVP in Diameter charging base, which has support for calls.

I can put down my pitchfork and go and hug my E1 links knowing they’re safe.

Walled Gardens & Redirection in 4G/5G (RedirectInformation)

PFCP includes a “Redirect Information” IE, which if set, allows you to change the forwarding action in PFCP to Redirect traffic.

We use this for walled garden redirects, when the OCS reports credit exhausted to the PGW-C, the PGW-C can tell the UPF (PGW-U) that all the traffic from a given subscriber should be redirected to a captive portal / walled garden, like a “Topup Now Page” you’d be used to seeing on Airport WiFi.

“Sign in to network” prompt presented on Cellular

Here’s what the spec says:

8.37. Redirect-Server AVP The Redirect-Server AVP (AVP Code 434) is of type Grouped and contains the address information of the redirect server (e.g., HTTP redirect server, SIP Server) with which the end user is to be connected when the account cannot cover the service cost. It MUST be present when the Final-Unit-Action AVP is set to REDIRECT. It is defined as follows (per the grouped-avp-def of RFC 3588 [DIAMBASE]): Redirect-Server ::= < AVP Header: 434 > { Redirect-Address-Type } { Redirect-Server-Address }

So how does this work in practice?

Once upon a time, you’d just intercept all HTTP request and serve your own content, but it’s not 2005 on Starbucks WiFi anymore, and SSL is everywhere.

Luckily this is a (mostly) solved problem, Apple has “Captive Network Assistant” that probes http://captive.apple.com/hotspot-detect.html and checks for a specific response, Google’s Android has http://connectivitycheck.gstatic.com/generate_204 and does the same thing.

There is a draft RFC to do this better, but it’s not widely adopted.

But before I can tell you what we do, I’ll show you what we’re not doing before we do the doing so you can see what the do does by looking at what happens when we don’t – Clear?

Before we send any Session Modification Request with redirect I can do a DNS lookup, here’s an example from our test jig that goes to Facebook:

A Record lookup for facebook.com resolving to 57.145.8.1

This is just a regular A record DNS query wrapped up in GTP-U as it’d look from a eNB/gNB/SGW that gets an answer back also in GTP-U.

As we’ve already got a session up in our case, the SMF or PGW-C we sends the PFCP Session Modification Request I shared in the screenshot earlier to the UPF.

The Redirect Server Address in the Redirect Information IE in PFCP

We do a few things on the UPF at this point, the first, is that we block forwarding access to all IPs except 10.179.2.135 (The redirect server in the screenshot), and we steal / intercept all DNS queries.

This means if you query facebook.com after the Redirect Information is in place, you get back an A-Record answer for facebook.com but it’s telling you Facebook lives on our redirect server.

We’ve got a whitelist on our UPF for certain domains, so if we’re sending you to a self-signup page, you’re going to need to be able to hit our payment processors portals (Stripe, Paypal, etc), so we need to allow their domains, but we don’t know their IPs, so instead we do server side DNS lookups (via our DNS servers before you sneaky kids get any other ideas) for the whitelsited domains, and if it’s on our DNS whitelist, we allow resolution to those domains and allow access to those IPs returned in the DNS response.

In my lab I’m redirecting HTTP traffic to a management server

Turning it off just involves sending another PFCP Session Modification Request but without the redirect information.

Once this is set we’re back resolving addresses.

Packet Buffering in the UPF

When a UE enters Idle mode, the network releases radio resources and the UE enters power saving mode.

When the UE wants to send data (Uplink) the UE just tells the network “hey I want to send something” and away it goes, nice and simple.

But when the network wants to send data to the UE (Downlink) then the UPF needs a method to tell the Control Plane (SGW-C or SMF) that there’s data waiting and to go and page the UE.

A prime example of this is when you’ve got a Mobile Terminated VoLTE call coming in, you need a way to tell the UE to wake up out of Idle mode because you’ve got something to send to it (a SIP INVITE).

But in order for this to work, we can’t just say “Hey I’ve got some packets for you” and let them get dropped, the UPF also needs to buffer (store temporarily) the downlink packets for the UE until the UE comes out of Idle mode, and then flush them out to deliver them to the UE.

So let’s look at the flow.

Enabling Buffering (Idle Mode)

When the sub enters idle mode, the Control Plane (SGW-C for an EPC or SMF for a 5GC) it sends a Session Modification Request but with the BUFF (Buffer) and NOCP (Notify Control Plane) flags set, and FORW (Forward) turned off.

What this means is now for packets to that bearer, the UPF must:

  • Not forward any traffic
  • Buffer the traffic
  • Notify the control plane when the first packet comes in that we buffer

Then the UPF just sits and waits for any incoming packets.

The Notify

When the UE gets an incoming packet that it’s supposed to buffer and notify, well, it does just that.

The packets are copied into a buffer, in sequence, and for the first packet, the UPF must send a notification to the Control Plane.

That looks like this, it’s just a Session Report Request with the Dowlink Data Report flag.

Now the SMF/SGW-U sends back a Session Report Response and starts the process of paging the UE.

At the same time the UPF keeps buffering – It’s work is not done.

Flushing and Forwarding

Once the UE has become reachable, the Control Panel needs to modify the bearer to turn back on forwarding. It does through another Session Modification Request, this is the inverse of the one it sent to turn on buffering, as we’re turning off buffering and notifications, and turning on forwarding.

Now the UPF flushes it’s buffer – It’ll send all the packets that were queued up out over the wire towards the gNB / eNodeB, so the SIP INVITE for the MT call or whatever will make it through.

One thing to note is that the packets that get buffered are going to take some time to get delivered, as the NOTIFY / page UE / reconnect UE / Session Modification Request (to enable forwarding again) needs to happen before the buffers are flushed and delivered.

Notice the latency spike on the first packet? 610ms? That’s because the UE had to be paged to wake up.

And that’s pretty much it, the UPF has now flushed it’s buffers and moves back to forwarding actions.

Network Instance in PFCP

I was recently looking for a field I could use in PFCP to denote the VRF / Network Segment to be used, and initially thought Network Instance would be perfect for this.

It’s not.

Network Instance is kinda preferred over the APN/DNN for decisions, for example a Packet Detection Rule (PDR) does not give a damn what you’ve set as the APN/DNN, only what the Network Instance is set to:

a combination of the parameters, that incoming packets are requested to match, among: Local F-TEID, Network
Instance, UE IP address(es), SDF Filter(s) and/or Application ID. For 5GC, the PDI may additionally contain
one or more QFI(s) to detect traffic pertaining to specific QoS flow(s), Ethernet Packet Filter(s) and/or Ethernet
PDU Session Information (see clause 5.13.1).

TS 129 244 – 5.2.1A Packet Detection Rule Handling

So the PDRs actually look at Network Instance not APN/DNN.

Well, back to the drawing board…

Tales from the Trenches – Samsung mystery packet on IMS Call

So we’ve found this scenario that occurs on some Samsung UEs, in certain radio contions, where midway through an otherwise normal voice call, the UE sends “mystery” data (Not IP data), which in turn causes the UPF to send the error indication and drop the bearer, which in turn drops the call.

The call starts, like any normal call, SIP REGISTER, INVITE, etc.

The P-CSCF / PCRF / PGW set up the dedicated bearer for the voice traffic, and the RTP stream starts flowing over it.

Then the UE sends these weird packets instead of the RTP stream:

These are GTP-U encapsulated data, with the TEID that matches the TEID used for the RTP stream, but there’s no IP data in them – they’re only 14 bytes long and sent by the UE.

Here’s some examples of what’s sent (each line is a packet):

d097ab7d605665f4f8f7cf7805c0
...
d198c445614c64f4f8f7cf7805c0
...
d298fd4d624263f4f8f7cf7805c0
...
d398be55633862f4f8f7cf7805c0
...
d498f45d642e61f4f8f7cf7805c0

Per 3GPP you can’t transmit anything other than IPv4 or IPv6 unless you’re using NIDD, but this is not using NIDD or Ethernet.

An IPv4 header is 20 bytes long, and IPv6 header is 40, so this is too short for either of those protocols, but what else could it be?

There’s some commonality of course, starts d0 as the first octet, then d1, d2, d3, etc. So that’s something?

I thought perhaps it was a boundary issue, that the standard RTP packet was being split across multiple GTP-U payloads, but that doesn’t appear to be the case.

An Ethernet header is 14 bytes, but if we were to decode this as Ethernet there’s still nothing it’s transporting, and the destination MAC is changing sequentailly if that’s the case, which would be even weirder.

I also thought about RTP that for some reason has lost it’s IP/UDP header, as the sequentially counting byte at the start could be the RTP sequence number, but that’d be 19 bytes minimum and the sequence number is the 3rd and 4th byte, not the first.

Whatever they contain, we see this sent over and over for a few seconds, then bam, back to normal RTP stream flowing.

Or at least it should be, but the invalid packet causes the UPF to generate a GTP-U Error Indication.

These Error Indication payloads eventually lead to the next PFCP Session Report Request having the Error Indication Report (ERIR) flag set to True.

When the PGW-U gets this, it sends a Session Delete Request, which dutifully drops the bearer.

Meaning the session drops on the EPC side, and the RTP drops with it, eventually a BYE is sent from the phone due to RTP timeout.

The above screenshot shows a different cause of GTP-U Error Indication – At this point the bearer has been dropped on the EPC side and these are Error Indications to report it doesn’t know the TIED / bearer.

How to fix this?

Well, unlikely we’ll get a fix on the Samsung side, so we’ll need to not drop the bearer on the PGW-C if we get a lot of Error Indications, and hope for the best.