fix(qos): repair PFCP session modification with remove+create rules
Related Issue(s) / Merge Request(s)
- https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-smf/-/merge_requests/328
- https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/merge_requests/253
Description
A PFCP Session Modification that removes some rules and creates new ones (the pattern an SMF uses to reconfigure QoS flows) left the UE unable to pass traffic between N3 and N6 and could stall the N4 handler. After forwarding was resolved, changed GBR/MBR values never reached the data plane. This MR makes session modification rebuild the data plane correctly, exactly once, from the session's final state, and tears down/rebuilds QoS (HTB/TC) state idempotently.
Issues resolved (summary):
- Issue: the modification handler rebuilt the BPF pipeline once per removed rule; only the final rebuild reflected the created rules. Solution: Rebuild the data plane *once, after all remove/create/update deltas are applied to the session.
- Issue:
ModifySessionre-applied themod_reqdeltas that pfcp_switch had already applied, and re-running removal would drop a created rule that reused a removed rule ID. Solution: Make the datapath callback a pure resync of the session's current rule set. - Issue:
rules_match_pdr_map/sdf_filters_mapwere only ever written, never pruned, so removed PDRs/QFIs lingered. Solution: Clear a session's per-rule entries before re-populating (and on session removal). - Issue:
session_qos_enabled_mapwas set but never cleared, and the priorQERProgramwas replaced withoutTearDown(). Solution: Clear the flag and tear down the previous program on rebuild / QoS-disable. - Issue:
QERProgram::Setupusedtc class add(fails File exists on an existing class, keeping the oldceil/MBR) and never removed classes for deleted QFIs. Solution: Track created class IDs and delete this session's subtree (children before parent) inTearDown, soSetuprebuilds with current values. Scoped per-SEID. - Issue: deadlock - public CRUD helpers lock then call the locking
GetSession(). Solution: AddGetSessionLocked()for callers already holding the lock. - Issue:
CategorizePdrsappended without clearing. Solution: Rebuild the views each call. - Issue: static-IP re-attach broke the data path. session_by_ue_ip_map (keyed by UE IP, used for both uplink and downlink) was never cleared on session deletion, and StorePduSessionInMap kept the existing SEID, so after re-attach with the same IP the entry still pointed at the deleted session and traffic was dropped. Solution: Clear the map entry on session removal, and take over the entry (refreshing TEIDs) when a different SEID claims the UE IP.
Tested Environment (e.g., radios, interfaces, CN)
Configuration Updates (e.g., files, parameters)
None. No config schema or parameter changes.
Known Issues / Limitations
- Rebuilding the session's HTB class tree on every modification means in-flight shaped traffic for that session sees a sub-millisecond gap (packets pass unshaped) during the del→add window.
- SMF guidance: when reconfiguring an existing flow, prefer Update PDR/FAR/QER over remove+create, and ensure created PDRs carry UE IP / F-TEID and FARs carry Outer Header Creation.
Checklist
- Code follows project coding standards.
- Relevant tests have been added or updated.
- Documentation has been updated where necessary.
- Configuration changes have been validated in the target environment(s). (N/A — no config changes; data-plane behaviour validated via tc/bpftool/iperf3.)
Log files or packet captures (PCAPs)
For the UE re-attach issue free5gc_static_ip_reattach.pcapng