Files: src/upf_app/user/qer_tc_user.h, qer_tc_user.cpp
Summary
Setup() issues bare tc class add for the PDU-session class, the default class, its PFIFO
child and one class per GBR/MBR QER, with no existence guard. Class ids are a deterministic
hash of (SEID, QFI) via generate_minor_id() — a pure hash with no counter — so a second
Setup() for the same session and QFI always targets the class the first one created.
tc class add then fails with File exists and the old rate and ceiling stay in place.
The PFCP response is an accept either way. Nothing in the signalling distinguishes
"applied" from "silently ignored", which is what makes this dangerous rather than merely
wrong.
Reproduce
cd ci-scripts/tests
sudo ./setup_env.sh
docker compose -f docker-compose.yaml restart upf # see note below
./run_scenarios.py --scenario qos_rate_change --scenario qos_rebuild_tc_failures -v
| Scenario |
Expected |
Observed |
qos_rate_change — enforced rate after an update to 20000/40000 |
20000/40000 |
50000/100000 — unchanged |
qos_rebuild_tc_failures — failed tc operations while applying it |
0 |
6 |
The pairing is the point. A fix that stopped the tc failures without actually applying the
new rate would turn one green and leave the other red.
Restart the UPF first. Deleted sessions leak their classes (see the shaping-state
issue), and because the class id is a hash of (SEID, QFI), whether a later run collides
with leftovers depends on where the SEID counter reached. On a dirty UPF qos_rate_change
has been observed to pass by luck.
ci-scripts/tests/upf_test/scenarios/06-qos_rate_change.py
ci-scripts/tests/upf_test/scenarios/14-qos_tc_failures.py
Suggested fix
Track the classes a QERTCProgram created and give Setup() a delete-then-add or a
tc class change path for a classid that already exists, rather than an unguarded add.
Surfacing a failed tc invocation as an error instead of a log line would also stop this
class of defect being silent — a modification that failed to reach the data plane should not
be answered with "Request accepted".
Related: PR #5 (the test suite).
Files:
src/upf_app/user/qer_tc_user.h,qer_tc_user.cppSummary
Setup()issues baretc class addfor the PDU-session class, the default class, its PFIFOchild and one class per GBR/MBR QER, with no existence guard. Class ids are a deterministic
hash of (SEID, QFI) via
generate_minor_id()— a pure hash with no counter — so a secondSetup()for the same session and QFI always targets the class the first one created.tc class addthen fails with File exists and the old rate and ceiling stay in place.The PFCP response is an accept either way. Nothing in the signalling distinguishes
"applied" from "silently ignored", which is what makes this dangerous rather than merely
wrong.
Reproduce
qos_rate_change— enforced rate after an update to 20000/40000qos_rebuild_tc_failures— failedtcoperations while applying itThe pairing is the point. A fix that stopped the
tcfailures without actually applying thenew rate would turn one green and leave the other red.
ci-scripts/tests/upf_test/scenarios/06-qos_rate_change.pyci-scripts/tests/upf_test/scenarios/14-qos_tc_failures.pySuggested fix
Track the classes a
QERTCProgramcreated and giveSetup()a delete-then-add or atc class changepath for a classid that already exists, rather than an unguarded add.Surfacing a failed
tcinvocation as an error instead of a log line would also stop thisclass of defect being silent — a modification that failed to reach the data plane should not
be answered with "Request accepted".
Related: PR #5 (the test suite).