aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2022-11-02 19:52:19 +0100
committerPau Espin Pedrol <pespin@sysmocom.de>2022-11-02 20:33:39 +0100
commit9f1f747d8ee89743951eae1db6cda2de5e5b9848 (patch)
tree47eca532710d41375c095f5523210c42a0a8a109
parentb9036af7caeb6de8757cae59ed0b8d2055f1954e (diff)
ggsn: Introduce tdef and make it configurable over VTY
-rw-r--r--ggsn/ggsn.h2
-rw-r--r--ggsn/ggsn_main.c6
-rw-r--r--ggsn/ggsn_vty.c4
-rw-r--r--gtp/gsn.c33
-rw-r--r--gtp/gsn.h12
-rw-r--r--gtp/gtp.c9
6 files changed, 53 insertions, 13 deletions
diff --git a/ggsn/ggsn.h b/ggsn/ggsn.h
index 132d059..46f8778 100644
--- a/ggsn/ggsn.h
+++ b/ggsn/ggsn.h
@@ -6,6 +6,7 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/select.h>
#include <osmocom/core/timer.h>
+#include <osmocom/core/tdef.h>
#include <osmocom/ctrl/control_if.h>
#include "../lib/tun.h"
@@ -152,6 +153,7 @@ struct apn_ctx *ggsn_find_or_create_apn(struct ggsn_ctx *ggsn, const char *name)
/* ggsn_main.c */
extern struct ctrl_handle *g_ctrlh;
extern void *tall_ggsn_ctx;
+extern struct osmo_tdef_group ggsn_tdef_group[];
/* ggsn.c */
extern int ggsn_start(struct ggsn_ctx *ggsn);
diff --git a/ggsn/ggsn_main.c b/ggsn/ggsn_main.c
index 88c3f68..2d917c1 100644
--- a/ggsn/ggsn_main.c
+++ b/ggsn/ggsn_main.c
@@ -34,6 +34,7 @@
#include <osmocom/core/stats.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/timer.h>
+#include <osmocom/core/tdef.h>
#include <osmocom/core/utils.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/control_cmd.h>
@@ -60,6 +61,11 @@ struct ul255_t apn;
static char *config_file = "osmo-ggsn.cfg";
+struct osmo_tdef_group ggsn_tdef_group[] = {
+ {.name = "gtp", .tdefs = gtp_T_defs, .desc = "GTP (libgtp) timers" },
+ { }
+};
+
/* To exit gracefully. Used with GCC compilation flag -pg and gprof */
static void signal_handler(int s)
{
diff --git a/ggsn/ggsn_vty.c b/ggsn/ggsn_vty.c
index 9591bf7..fb0caa2 100644
--- a/ggsn/ggsn_vty.c
+++ b/ggsn/ggsn_vty.c
@@ -33,6 +33,7 @@
#include <osmocom/vty/command.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/misc.h>
+#include <osmocom/vty/tdef_vty.h>
#include "../gtp/gtp.h"
#include "../gtp/pdp.h"
@@ -795,6 +796,7 @@ static int config_write_ggsn(struct vty *vty)
vty_out(vty, " gtp control-ip %s%s", in46a_ntoa(&ggsn->cfg.gtpc_addr), VTY_NEWLINE);
if (ggsn->cfg.gtpu_addr.v4.s_addr)
vty_out(vty, " gtp user-ip %s%s", in46a_ntoa(&ggsn->cfg.gtpu_addr), VTY_NEWLINE);
+ osmo_tdef_vty_groups_write(vty, " ");
llist_for_each_entry(apn, &ggsn->apn_list, list)
config_write_apn(vty, apn);
if (ggsn->cfg.default_apn)
@@ -1113,6 +1115,8 @@ int ggsn_vty_init(void)
install_element(GGSN_NODE, &cfg_ggsn_echo_interval_cmd);
install_element(GGSN_NODE, &cfg_ggsn_no_echo_interval_cmd);
+ osmo_tdef_vty_groups_init(GGSN_NODE, ggsn_tdef_group);
+
install_node(&apn_node, NULL);
install_element(APN_NODE, &cfg_description_cmd);
install_element(APN_NODE, &cfg_no_description_cmd);
diff --git a/gtp/gsn.c b/gtp/gsn.c
index 2189725..da30fc9 100644
--- a/gtp/gsn.c
+++ b/gtp/gsn.c
@@ -62,11 +62,6 @@
#include "gtpie.h"
#include "queue.h"
-/* According to section 14.2 of 3GPP TS 29.006 version 6.9.0 */
-#define N3_REQUESTS 5
-
-#define T3_REQUEST 3
-
/* Error reporting functions */
#define LOGP_WITH_ADDR(ss, level, addr, fmt, args...) \
@@ -104,6 +99,18 @@ static const struct rate_ctr_group_desc gsn_ctrg_desc = {
};
static unsigned int gsn_ctr_next_idx = 0;
+/* Global timer definitions for GTP operation, provided for convenience. To make these user configurable, it is convenient to add
+ * gtp_gsn_tdefs as one of your program's osmo_tdef_group entries and call osmo_tdef_vty_init(). */
+struct osmo_tdef gtp_T_defs[] = {
+ { .T = GTP_GSN_TIMER_T3_RESPONSE, .default_val = 5, .unit = OSMO_TDEF_S,
+ .desc = "Timer T3-RESPONSE holds the maximum wait time for a response of a request message"
+ },
+ { .T = GTP_GSN_TIMER_N3_REQUESTS, .default_val = 3, .unit = OSMO_TDEF_CUSTOM,
+ .desc = "Counter N3-REQUESTS holds the maximum number of attempts made by GTP to send a request message"
+ },
+ {}
+};
+
/* API Functions */
@@ -241,13 +248,17 @@ static int queue_timer_retrans(struct gsn_t *gsn)
/* Remove from queue if maxretrans exceeded */
time_t now;
struct qmsg_t *qmsg;
+ unsigned int t3_response, n3_requests;
+
now = time(NULL);
+ t3_response = osmo_tdef_get(gsn->tdef, GTP_GSN_TIMER_T3_RESPONSE, OSMO_TDEF_S, -1);
+ n3_requests = osmo_tdef_get(gsn->tdef, GTP_GSN_TIMER_N3_REQUESTS, OSMO_TDEF_CUSTOM, -1);
/* get first element in queue, as long as the timeout of that
* element has expired */
while ((!queue_getfirst(gsn->queue_req, &qmsg)) &&
(qmsg->timeout <= now)) {
- if (qmsg->retrans > N3_REQUESTS) { /* Too many retrans */
+ if (qmsg->retrans > n3_requests) { /* Too many retrans */
LOGP(DLGTP, LOGL_NOTICE, "Retransmit req queue timeout of seq %" PRIu16 "\n",
qmsg->seq);
if (gsn->cb_conf)
@@ -266,7 +277,7 @@ static int queue_timer_retrans(struct gsn_t *gsn)
qmsg->l, strerror(errno));
}
queue_back(gsn->queue_req, qmsg);
- qmsg->timeout = now + T3_REQUEST;
+ qmsg->timeout = now + t3_response;
qmsg->retrans++;
}
}
@@ -424,6 +435,14 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
/* Initialise sequence number */
(*gsn)->seq_next = (*gsn)->restart_counter * 1024;
+ /* Initialize timers: */
+ (*gsn)->tdef = gtp_T_defs;
+ /* Small hack to properly reset tdef for old clients not using the tdef_group: */
+ osmo_static_assert(gtp_T_defs[0].default_val != 0, first_default_val_not_zero);
+ if (gtp_T_defs[0].val == 0)
+ osmo_tdefs_reset((*gsn)->tdef);
+
+
/* Initialise request retransmit queue */
queue_new(&(*gsn)->queue_req);
queue_new(&(*gsn)->queue_resp);
diff --git a/gtp/gsn.h b/gtp/gsn.h
index cbe5b27..3b9cb1d 100644
--- a/gtp/gsn.h
+++ b/gtp/gsn.h
@@ -15,6 +15,7 @@
#include <osmocom/core/utils.h>
#include <osmocom/core/defs.h>
#include <osmocom/core/timer.h>
+#include <osmocom/core/tdef.h>
#include <osmocom/core/rate_ctr.h>
#include "pdp.h"
@@ -24,6 +25,8 @@
#define RESTART_FILE "gsn_restart"
+extern struct osmo_tdef gtp_T_defs[];
+
/* ***********************************************************
* Information storage for each gsn instance
*
@@ -60,6 +63,12 @@ enum gsn_rate_ctr_keys {
GSN_CTR_PKT_INVALID, /* Number of invalid message format messages */
};
+/* 3GPP TS 29.006 14.1, 14,2 */
+enum gtp_gsn_timers {
+ GTP_GSN_TIMER_T3_RESPONSE = 3,
+ GTP_GSN_TIMER_N3_REQUESTS = 1003,
+};
+
struct gsn_t {
/* Parameters related to the network interface */
@@ -100,6 +109,9 @@ struct gsn_t {
/* Counters */
struct rate_ctr_group *ctrg;
+
+ /* Timers: */
+ struct osmo_tdef *tdef;
};
/* External API functions */
diff --git a/gtp/gtp.c b/gtp/gtp.c
index 7e1a03f..f32461c 100644
--- a/gtp/gtp.c
+++ b/gtp/gtp.c
@@ -60,11 +60,6 @@
#include "gtpie.h"
#include "queue.h"
-/* According to section 14.2 of 3GPP TS 29.006 version 6.9.0 */
-#define N3_REQUESTS 5
-
-#define T3_REQUEST 3
-
/* Error reporting functions */
#define GTP_LOGPKG(pri, peer, pack, len, fmt, args...) \
@@ -400,11 +395,13 @@ static int gtp_req(struct gsn_t *gsn, uint8_t version, struct pdp_t *pdp,
LOGP(DLGTP, LOGL_ERROR, "Retransmit req queue is full (seq=%" PRIu16 ")\n",
gsn->seq_next);
} else {
+ unsigned int t3_response;
LOGP(DLGTP, LOGL_DEBUG, "Registering seq=%" PRIu16
" in restransmit req queue\n", gsn->seq_next);
+ t3_response = osmo_tdef_get(gsn->tdef, GTP_GSN_TIMER_T3_RESPONSE, OSMO_TDEF_S, -1);
memcpy(&qmsg->p, packet, sizeof(union gtp_packet));
qmsg->l = len;
- qmsg->timeout = time(NULL) + T3_REQUEST; /* When to timeout */
+ qmsg->timeout = time(NULL) + t3_response; /* When to timeout */
qmsg->retrans = 0; /* No retransmissions so far */
qmsg->cbp = cbp;
qmsg->type = ntoh8(packet->gtp0.h.type);