aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2019-05-29 20:42:09 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2019-05-31 16:34:32 +0200
commit0d0b0592f09699c6eb7bca871f126be859a23443 (patch)
tree7d2cc997660c43e1d6c9875ffa1f14afc2dab43f
parentaad77a0acfa65189aebf92bcbf63715f359c9b1a (diff)
gtp: Refactor code to use gtp_freepdp(_teardown) APIs
* API gtp_freepdp was already there but was not really being used by anyone currently, so we can change its behaviour to call cb_delete_ctx. It makes sense to call the cb in there too to be consistent with rest of APIs. * Add API gtp_freepdp_teardown, which calls gtp_freepdp on pdp and its secondary contexts. It will also be used later on by osmo-ggsn. * Use new APIs in internal code to simplify it. Change-Id: I9f0b774e9385a7a8d81ec9702f158e2f9a50d571
-rw-r--r--gtp/gtp.c81
-rw-r--r--gtp/gtp.h1
2 files changed, 32 insertions, 50 deletions
diff --git a/gtp/gtp.c b/gtp/gtp.c
index 6e834cc..57c19a2 100644
--- a/gtp/gtp.c
+++ b/gtp/gtp.c
@@ -146,9 +146,36 @@ int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp)
{
+ if (gsn->cb_delete_context)
+ gsn->cb_delete_context(pdp);
return pdp_freepdp(pdp);
}
+/* Free pdp and all its secondary PDP contexts. Must be called on the primary PDP context. */
+int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp)
+{
+ int n;
+ struct pdp_t *secondary_pdp;
+ OSMO_ASSERT(!pdp->secondary);
+
+ for (n = 0; n < PDP_MAXNSAPI; n++) {
+ if (pdp->secondary_tei[n]) {
+ if (pdp_getgtp1
+ (&secondary_pdp,
+ pdp->secondary_tei[n])) {
+ LOGP(DLGTP, LOGL_ERROR,
+ "Unknown secondary PDP context\n");
+ continue;
+ }
+ if (pdp != secondary_pdp) {
+ gtp_freepdp(gsn, secondary_pdp);
+ }
+ }
+ }
+
+ return gtp_freepdp(gsn, pdp);
+}
+
/* gtp_gpdu */
extern int gtp_fd(struct gsn_t *gsn)
@@ -1648,9 +1675,7 @@ int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
DEBUGP(DLGTP, "gtp_create_pdp_ind: Deleting old context\n");
- if (gsn->cb_delete_context)
- gsn->cb_delete_context(pdp_old);
- pdp_freepdp(pdp_old);
+ gtp_freepdp(gsn, pdp_old);
DEBUGP(DLGTP, "gtp_create_pdp_ind: Deleted...\n");
}
@@ -2371,8 +2396,6 @@ int gtp_delete_context_req(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp,
int teardown)
{
struct pdp_t *linked_pdp;
- struct pdp_t *secondary_pdp;
- int n;
if (pdp_getgtp1(&linked_pdp, pdp->teic_own)) {
LOGP(DLGTP, LOGL_ERROR,
@@ -2384,26 +2407,7 @@ int gtp_delete_context_req(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp,
return EOF;
if (teardown) { /* Remove all contexts */
- for (n = 0; n < PDP_MAXNSAPI; n++) {
- if (linked_pdp->secondary_tei[n]) {
- if (pdp_getgtp1
- (&secondary_pdp,
- linked_pdp->secondary_tei[n])) {
- LOGP(DLGTP, LOGL_ERROR,
- "Unknown secondary PDP context\n");
- return EOF;
- }
- if (linked_pdp != secondary_pdp) {
- if (gsn->cb_delete_context)
- gsn->cb_delete_context
- (secondary_pdp);
- pdp_freepdp(secondary_pdp);
- }
- }
- }
- if (gsn->cb_delete_context)
- gsn->cb_delete_context(linked_pdp);
- pdp_freepdp(linked_pdp);
+ gtp_freepdp_teardown(gsn, linked_pdp);
} else {
if (gsn->cb_delete_context)
gsn->cb_delete_context(pdp);
@@ -2470,10 +2474,8 @@ int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
uint8_t cause, int teardown)
{
union gtp_packet packet;
- struct pdp_t *secondary_pdp;
unsigned int length =
get_default_gtp(version, GTP_DELETE_PDP_RSP, &packet);
- int n;
gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_CAUSE, cause);
@@ -2482,26 +2484,7 @@ int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
if (cause == GTPCAUSE_ACC_REQ) {
if ((teardown) || (version == 0)) { /* Remove all contexts */
- for (n = 0; n < PDP_MAXNSAPI; n++) {
- if (linked_pdp->secondary_tei[n]) {
- if (pdp_getgtp1
- (&secondary_pdp,
- linked_pdp->secondary_tei[n])) {
- LOGP(DLGTP, LOGL_ERROR,
- "Unknown secondary PDP context\n");
- return EOF;
- }
- if (linked_pdp != secondary_pdp) {
- if (gsn->cb_delete_context)
- gsn->cb_delete_context
- (secondary_pdp);
- pdp_freepdp(secondary_pdp);
- }
- }
- }
- if (gsn->cb_delete_context)
- gsn->cb_delete_context(linked_pdp);
- pdp_freepdp(linked_pdp);
+ gtp_freepdp_teardown(gsn, linked_pdp);
} else { /* Remove only current context */
if (gsn->cb_delete_context)
gsn->cb_delete_context(pdp);
@@ -2752,9 +2735,7 @@ static int gtp_error_ind_conf(struct gsn_t *gsn, uint8_t version,
* code should ever change. */
OSMO_ASSERT(pdp);
- if (gsn->cb_delete_context)
- gsn->cb_delete_context(pdp);
- pdp_freepdp(pdp);
+ gtp_freepdp(gsn, pdp);
return 0;
}
diff --git a/gtp/gtp.h b/gtp/gtp.h
index 5f35ab5..6582319 100644
--- a/gtp/gtp.h
+++ b/gtp/gtp.h
@@ -309,6 +309,7 @@ extern int gtp_free(struct gsn_t *gsn);
extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
uint64_t imsi, uint8_t nsapi);
extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp);
+extern int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp);
extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
void *cbp);