ggsn: Introduce tdef and make it configurable over VTY
Related: OS#5485 Change-Id: I10bc8e2e197c0e8753b23b684b5ae41025672bf7
This commit is contained in:
parent
b9036af7ca
commit
9f1f747d8e
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
33
gtp/gsn.c
33
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);
|
||||
|
|
12
gtp/gsn.h
12
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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue