From 9f1f747d8ee89743951eae1db6cda2de5e5b9848 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Wed, 2 Nov 2022 19:52:19 +0100 Subject: [PATCH] ggsn: Introduce tdef and make it configurable over VTY Related: OS#5485 Change-Id: I10bc8e2e197c0e8753b23b684b5ae41025672bf7 --- ggsn/ggsn.h | 2 ++ ggsn/ggsn_main.c | 6 ++++++ ggsn/ggsn_vty.c | 4 ++++ gtp/gsn.c | 33 ++++++++++++++++++++++++++------- gtp/gsn.h | 12 ++++++++++++ gtp/gtp.c | 9 +++------ 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 #include #include +#include #include #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 #include #include +#include #include #include #include @@ -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 #include #include +#include #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 #include #include +#include #include #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);