Skip to content

GGSN Delete PDP Context ignores Teardown Ind and NSAPI — deactivating one context tears down the PDN connection #129

Description

@next-nf

Found while doing #109, which gives a secondary PDP context a user plane worth keeping.

What happens

ggsn_gn:handle_request/5 for delete_pdp_context_request (apps/smf_core/src/ggsn_gn.erl:246) discards the request's IEs entirely — ie = _IEs — and runs smf_gtp_gsn_lib:close_context_proc(?API, normal, Data0) on the whole context:

handle_request(ReqKey,
	       #gtp{type = delete_pdp_context_request, ie = _IEs} = Request,
	       _Resent, #{session := connected} = State,
	       #{tunnels := #{'Access' := AccessTunnel}} = Data0) ->
    Proc = smf_gtp_gsn_lib:close_context_proc(?API, normal, Data0),

Neither the NSAPI (mandatory) nor the Teardown Ind (conditional) is read, so every Delete PDP Context Request deactivates the entire PDN connection.

What the spec requires (TS 29.060 §7.3.5, IE definition §7.7.16)

  • Teardown Ind 1 ⇒ "all PDP contexts that share the same PDN connection with the PDP context identified by the NSAPI … shall be torn down". Teardown Ind 0 or absent ⇒ only the identified context.
  • Whole-PDN-connection semantics come from the Teardown Ind, not from which NSAPI is named — unlike EPS, where naming the LBI is what means "tear everything down".
  • The race guard: "If a GSN receives a Delete PDP context without a Teardown Indicator or with a Teardown Indicator with value set to '0' and only that PDP context is active for a PDN connection, then the GSN shall ignore the message." Not reject — ignore. "This is symptom of a race condition. The reliable delivery of signalling messages will eventually lead to a consistent situation."

So there are three behaviours here and the code implements one of them unconditionally.

Why it matters more now

Before #109 a secondary PDP context carried no user plane, so collapsing the whole connection on any deactivation lost little. Now that a secondary context gets its own bound PCC rule, PDR and GTP-U tunnel, an MS deactivating one service tears down the primary context's user plane with it.

What a fix needs

  • Read #nsapi{} and #teardown_ind{} from the request.
  • Teardown Ind = 1, or the named NSAPI is the last active context: today's whole-context close.
  • Teardown Ind 0/absent with other contexts active: remove just that bearer — drop {'Access', NSAPI} and its {bearer_id, _} entry (smf_gsn_lib:remove_bearer_metadata_for_ebi/2 already does the metadata half), report the removal to the PCRF with Bearer-Operation TERMINATION (TS 29.212 A.3.1), and re-provision the UPF with one session modification.
  • Teardown Ind 0/absent when it is the only active context: ignore the message, no response.

Test gap

ggsn_SUITE only ever deletes a whole PDN connection. The cases above want: deactivate the secondary and assert the primary's PDR survives; deactivate with Teardown Ind = 1 and assert both go; send a Teardown-Ind-less delete for a single-context connection and assert no response and a live context.

Related: #109 (the secondary context's user plane), #128 (the TFT half of the same Gx exchange).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions