aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2019-08-28 16:54:16 +0200
committerpespin <pespin@sysmocom.de>2019-09-02 09:06:13 +0000
commit259e303436e035a5d137c17978f2f8de4bd58328 (patch)
tree4cb9ebe37504ac99b31811c60df96958f8f8eb80
parent6ec5dc26b394e060287da260f9a6a655278a23f8 (diff)
sgsn: gtp: Drop related pdp contexts on echo timeout against GGSN
-rw-r--r--include/osmocom/sgsn/gprs_sgsn.h1
-rw-r--r--src/gprs/gprs_sgsn.c5
-rw-r--r--src/gprs/sgsn_libgtp.c17
3 files changed, 16 insertions, 7 deletions
diff --git a/include/osmocom/sgsn/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h
index 17cafa3d1..eea9fb0b9 100644
--- a/include/osmocom/sgsn/gprs_sgsn.h
+++ b/include/osmocom/sgsn/gprs_sgsn.h
@@ -402,6 +402,7 @@ struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_addr(struct in_addr *addr);
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_find_alloc(uint32_t id);
void sgsn_ggsn_ctx_drop_pdp(struct sgsn_pdp_ctx *pctx);
int sgsn_ggsn_ctx_drop_all_pdp_except(struct sgsn_ggsn_ctx *ggsn, struct sgsn_pdp_ctx *except);
+int sgsn_ggsn_ctx_drop_all_pdp(struct sgsn_ggsn_ctx *ggsn);
void sgsn_ggsn_ctx_add_pdp(struct sgsn_ggsn_ctx *ggc, struct sgsn_pdp_ctx *pdp);
void sgsn_ggsn_ctx_remove_pdp(struct sgsn_ggsn_ctx *ggc, struct sgsn_pdp_ctx *pdp);
void sgsn_ggsn_ctx_check_echo_timer(struct sgsn_ggsn_ctx *ggc);
diff --git a/src/gprs/gprs_sgsn.c b/src/gprs/gprs_sgsn.c
index 7174bd5e2..829204ea9 100644
--- a/src/gprs/gprs_sgsn.c
+++ b/src/gprs/gprs_sgsn.c
@@ -759,6 +759,11 @@ int sgsn_ggsn_ctx_drop_all_pdp_except(struct sgsn_ggsn_ctx *ggsn, struct sgsn_pd
return num;
}
+int sgsn_ggsn_ctx_drop_all_pdp(struct sgsn_ggsn_ctx *ggsn)
+{
+ return sgsn_ggsn_ctx_drop_all_pdp_except(ggsn, NULL);
+}
+
void sgsn_ggsn_ctx_add_pdp(struct sgsn_ggsn_ctx *ggc, struct sgsn_pdp_ctx *pdp)
{
llist_add(&pdp->ggsn_list, &ggc->pdp_list);
diff --git a/src/gprs/sgsn_libgtp.c b/src/gprs/sgsn_libgtp.c
index 79d5543f2..a8ad527bc 100644
--- a/src/gprs/sgsn_libgtp.c
+++ b/src/gprs/sgsn_libgtp.c
@@ -469,7 +469,8 @@ void sgsn_pdp_upd_gtp_u(struct sgsn_pdp_ctx *pdp, void *addr, size_t alen)
void sgsn_ggsn_echo_req(struct sgsn_ggsn_ctx *ggc)
{
- gtp_echo_req(ggc->gsn, ggc->gtp_version, NULL, &ggc->remote_addr);
+ LOGGGSN(ggc, LOGL_INFO, "GTP Tx Echo Request\n");
+ gtp_echo_req(ggc->gsn, ggc->gtp_version, ggc, &ggc->remote_addr);
}
#ifdef BUILD_IU
@@ -579,13 +580,15 @@ static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
}
/* Confirmation of an GTP ECHO request */
-static int echo_conf(struct pdp_t *pdp, void *cbp, int recovery)
+static int echo_conf(void *cbp, bool timeout)
{
- if (recovery < 0) {
- LOGP(DGPRS, LOGL_NOTICE, "GTP Echo Request timed out\n");
+ struct sgsn_ggsn_ctx *ggc = (struct sgsn_ggsn_ctx *)cbp;
+ if (timeout) {
+ LOGGGSN(ggc, LOGL_NOTICE, "GTP Echo Request timed out\n");
/* FIXME: if version == 1, retry with version 0 */
+ sgsn_ggsn_ctx_drop_all_pdp(ggc);
} else {
- DEBUGP(DGPRS, "GTP Rx Echo Response\n");
+ LOGGGSN(ggc, LOGL_INFO, "GTP Rx Echo Response\n");
}
return 0;
}
@@ -630,8 +633,8 @@ static int cb_conf(int type, int cause, struct pdp_t *pdp, void *cbp)
switch (type) {
case GTP_ECHO_REQ:
- /* libgtp hands us the RECOVERY number instead of a cause */
- return echo_conf(pdp, cbp, cause);
+ /* libgtp hands us the RECOVERY number instead of a cause (EOF on timeout) */
+ return echo_conf(cbp, cause == EOF);
case GTP_CREATE_PDP_REQ:
return create_pdp_conf(pdp, cbp, cause);
case GTP_DELETE_PDP_REQ: