aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Couzens <lynxis@fe80.eu>2018-09-18 20:07:37 +0200
committerAlexander Couzens <lynxis@fe80.eu>2018-09-18 20:07:37 +0200
commit88de40600a716badc4c11ee671d838a331592b22 (patch)
tree4393ea9d944a2c1fda140b63c001120f877d96e7
parent859a3f8e7f066c7b14c6ce51ac517ccff025a835 (diff)
GTP: refactor the echo timerlynxis/staging
The gtp echo timer must be re-check everytime the echo-timer has been modified or deactivated. Fixes the TTCN3 SGSN_Tests.TC_attach_restart_ctr_echo Change-Id: Ia33471a9a9cfc3887facb665c82094b99932052a
-rw-r--r--include/osmocom/sgsn/gprs_sgsn.h1
-rw-r--r--src/gprs/gprs_sgsn.c23
-rw-r--r--src/gprs/sgsn_vty.c2
3 files changed, 20 insertions, 6 deletions
diff --git a/include/osmocom/sgsn/gprs_sgsn.h b/include/osmocom/sgsn/gprs_sgsn.h
index f7456859f..2658bd6c8 100644
--- a/include/osmocom/sgsn/gprs_sgsn.h
+++ b/include/osmocom/sgsn/gprs_sgsn.h
@@ -375,6 +375,7 @@ 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);
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);
struct apn_ctx {
struct llist_head list;
diff --git a/src/gprs/gprs_sgsn.c b/src/gprs/gprs_sgsn.c
index dc0e7c075..16ba979cc 100644
--- a/src/gprs/gprs_sgsn.c
+++ b/src/gprs/gprs_sgsn.c
@@ -489,12 +489,24 @@ void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp)
talloc_free(pdp);
}
+void sgsn_ggsn_ctx_check_echo_timer(struct sgsn_ggsn_ctx *ggc)
+{
+ if (llist_empty(&ggc->pdp_list) || ggc->echo_interval <= 0) {
+ /* stop timer */
+ if (osmo_timer_pending(&ggc->echo_timer))
+ osmo_timer_del(&ggc->echo_timer);
+ } else {
+ /* re-start timer */
+ sgsn_ggsn_echo_req(ggc);
+ osmo_timer_schedule(&ggc->echo_timer, ggc->echo_interval, 0);
+ }
+}
+
/* GGSN contexts */
static void echo_timer_cb(void *data)
{
struct sgsn_ggsn_ctx *ggc = (struct sgsn_ggsn_ctx *) data;
- sgsn_ggsn_echo_req(ggc);
- osmo_timer_schedule(&ggc->echo_timer, ggc->echo_interval, 0);
+ sgsn_ggsn_ctx_check_echo_timer(ggc);
}
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id)
@@ -742,15 +754,14 @@ int sgsn_ggsn_ctx_drop_all_pdp_except(struct sgsn_ggsn_ctx *ggsn, struct sgsn_pd
void sgsn_ggsn_ctx_add_pdp(struct sgsn_ggsn_ctx *ggc, struct sgsn_pdp_ctx *pdp)
{
- if (llist_empty(&ggc->pdp_list) && ggc->echo_interval > 0)
- osmo_timer_schedule(&ggc->echo_timer, ggc->echo_interval, 0);
+ sgsn_ggsn_ctx_check_echo_timer(ggc);
+
llist_add(&pdp->ggsn_list, &ggc->pdp_list);
}
void sgsn_ggsn_ctx_remove_pdp(struct sgsn_ggsn_ctx *ggc, struct sgsn_pdp_ctx *pdp)
{
llist_del(&pdp->ggsn_list);
- if (llist_empty(&ggc->pdp_list) && osmo_timer_pending(&ggc->echo_timer))
- osmo_timer_del(&ggc->echo_timer);
+ sgsn_ggsn_ctx_check_echo_timer(ggc);
if (pdp->destroy_ggsn)
sgsn_ggsn_ctx_free(pdp->ggsn);
pdp->ggsn = NULL;
diff --git a/src/gprs/sgsn_vty.c b/src/gprs/sgsn_vty.c
index de193f03a..63985bcd9 100644
--- a/src/gprs/sgsn_vty.c
+++ b/src/gprs/sgsn_vty.c
@@ -383,6 +383,7 @@ DEFUN(cfg_ggsn_echo_interval, cfg_ggsn_echo_interval_cmd,
"not be lower than 60 seconds, use this value for " \
"testing purposes only!%s", VTY_NEWLINE);
+ sgsn_ggsn_ctx_check_echo_timer(ggc);
return CMD_SUCCESS;
}
@@ -395,6 +396,7 @@ DEFUN(cfg_ggsn_no_echo_interval, cfg_ggsn_no_echo_interval_cmd,
struct sgsn_ggsn_ctx *ggc = sgsn_ggsn_ctx_find_alloc(id);
ggc->echo_interval = -1;
+ sgsn_ggsn_ctx_check_echo_timer(ggc);
return CMD_SUCCESS;
}