aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/sgsn/gb_proxy.h5
-rw-r--r--src/gprs/gb_proxy.c24
-rw-r--r--src/gprs/gb_proxy_vty.c38
3 files changed, 59 insertions, 8 deletions
diff --git a/include/osmocom/sgsn/gb_proxy.h b/include/osmocom/sgsn/gb_proxy.h
index 70de3d715..16082fcde 100644
--- a/include/osmocom/sgsn/gb_proxy.h
+++ b/include/osmocom/sgsn/gb_proxy.h
@@ -105,8 +105,12 @@ struct gbproxy_config {
struct osmo_plmn_id core_plmn;
uint8_t* core_apn;
size_t core_apn_size;
+ /* If !0, Max age to consider a struct gbproxy_link_info as stale */
int tlli_max_age;
+ /* If !0, Max len of gbproxy_peer->list (list of struct gbproxy_link_info) */
int tlli_max_len;
+ /* If !0, Max len of gbproxy_link_info->stored_msgs (list of msgb) */
+ uint32_t stored_msgs_max_len;
/* Experimental config */
int patch_ptmsi;
@@ -171,6 +175,7 @@ struct gbproxy_link_info {
int imsi_acq_pending;
struct llist_head stored_msgs;
+ uint32_t stored_msgs_len;
unsigned vu_gen_tx_bss;
int is_deregistered;
diff --git a/src/gprs/gb_proxy.c b/src/gprs/gb_proxy.c
index f834ed3e6..8bb67895e 100644
--- a/src/gprs/gb_proxy.c
+++ b/src/gprs/gb_proxy.c
@@ -338,7 +338,8 @@ static int gbproxy_flush_stored_messages(struct gbproxy_peer *peer,
msgb_nsei(msg));
/* Patch and flush stored messages towards the SGSN */
- while ((stored_msg = msgb_dequeue(&link_info->stored_msgs))) {
+ while ((stored_msg = msgb_dequeue_count(&link_info->stored_msgs,
+ &link_info->stored_msgs_len))) {
struct gprs_gb_parse_context tmp_parse_ctx = {0};
tmp_parse_ctx.to_bss = 0;
tmp_parse_ctx.peer_nsei = msgb_nsei(stored_msg);
@@ -492,6 +493,24 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer,
/* The message cannot be processed since the IMSI is still missing */
+ /* If queue is getting too large, drop oldest msgb before adding new one */
+ if (peer->cfg->stored_msgs_max_len > 0) {
+ int exceeded_max_len = link_info->stored_msgs_len
+ + 1 - peer->cfg->stored_msgs_max_len;
+
+ for (; exceeded_max_len > 0; exceeded_max_len--) {
+ struct msgb *msgb_drop;
+ msgb_drop = msgb_dequeue_count(&link_info->stored_msgs,
+ &link_info->stored_msgs_len);
+ LOGP(DLLC, LOGL_INFO,
+ "NSEI=%d(BSS) Dropping stored msgb from list "
+ "(!acq imsi, length %d, max_len exceeded)\n",
+ msgb_nsei(msgb_drop), link_info->stored_msgs_len);
+
+ msgb_free(msgb_drop);
+ }
+ }
+
/* Enqueue unpatched messages */
LOGP(DLLC, LOGL_INFO,
"NSEI=%d(BSS) IMSI acquisition in progress, "
@@ -500,7 +519,8 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer,
parse_ctx->llc_msg_name ? parse_ctx->llc_msg_name : "BSSGP");
stored_msg = bssgp_msgb_copy(msg, "process_bssgp_ul");
- msgb_enqueue(&link_info->stored_msgs, stored_msg);
+ msgb_enqueue_count(&link_info->stored_msgs, stored_msg,
+ &link_info->stored_msgs_len);
if (!link_info->imsi_acq_pending) {
LOGP(DLLC, LOGL_INFO,
diff --git a/src/gprs/gb_proxy_vty.c b/src/gprs/gb_proxy_vty.c
index cd10abfda..d74335556 100644
--- a/src/gprs/gb_proxy_vty.c
+++ b/src/gprs/gb_proxy_vty.c
@@ -23,6 +23,7 @@
#include <arpa/inet.h>
#include <string.h>
#include <time.h>
+#include <inttypes.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/rate_ctr.h>
@@ -128,6 +129,9 @@ static int config_write_gbproxy(struct vty *vty)
vty_out(vty, " link-list keep-mode %s%s",
get_value_string(keep_modes, g_cfg->keep_link_infos),
VTY_NEWLINE);
+ if (g_cfg->stored_msgs_max_len > 0)
+ vty_out(vty, " link stored-msgs-max-length %"PRIu32"%s",
+ g_cfg->stored_msgs_max_len, VTY_NEWLINE);
return CMD_SUCCESS;
@@ -402,6 +406,7 @@ DEFUN(cfg_gbproxy_no_secondary_sgsn,
}
#define GBPROXY_LINK_LIST_STR "Set TLLI list parameters\n"
+#define GBPROXY_LINK_STR "Set TLLI parameters\n"
#define GBPROXY_MAX_AGE_STR "Limit maximum age\n"
DEFUN(cfg_gbproxy_link_list_max_age,
@@ -464,6 +469,27 @@ DEFUN(cfg_gbproxy_link_list_keep_mode,
return CMD_SUCCESS;
}
+DEFUN(cfg_gbproxy_link_stored_msgs_max_len,
+ cfg_gbproxy_link_stored_msgs_max_len_cmd,
+ "link stored-msgs-max-length <1-99999>",
+ GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR
+ "Maximum number of msgb stored in the logical link waiting to acquire its IMSI\n")
+{
+ g_cfg->stored_msgs_max_len = (uint32_t) atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_gbproxy_link_no_stored_msgs_max_len,
+ cfg_gbproxy_link_no_stored_msgs_max_len_cmd,
+ "no link stored-msgs-max-length",
+ NO_STR GBPROXY_LINK_STR GBPROXY_MAX_LEN_STR)
+{
+ g_cfg->stored_msgs_max_len = 0;
+
+ return CMD_SUCCESS;
+}
+
DEFUN(show_gbproxy, show_gbproxy_cmd, "show gbproxy [stats]",
SHOW_STR "Display information about the Gb proxy\n" "Show statistics\n")
@@ -502,10 +528,6 @@ DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links",
llist_for_each_entry(link_info, &state->logical_links, list) {
time_t age = now - link_info->timestamp;
- int stored_msgs = 0;
- struct llist_head *iter;
- llist_for_each(iter, &link_info->stored_msgs)
- stored_msgs++;
if (link_info->imsi > 0) {
snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
@@ -518,8 +540,10 @@ DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links",
vty_out(vty, " TLLI %08x, IMSI %s, AGE %d",
link_info->tlli.current, mi_buf, (int)age);
- if (stored_msgs)
- vty_out(vty, ", STORED %d", stored_msgs);
+ if (link_info->stored_msgs_len)
+ vty_out(vty, ", STORED %"PRIu32"/%"PRIu32,
+ link_info->stored_msgs_len,
+ g_cfg->stored_msgs_max_len);
if (g_cfg->route_to_sgsn2)
vty_out(vty, ", SGSN NSEI %d",
@@ -825,6 +849,7 @@ int gbproxy_vty_init(void)
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_age_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_max_len_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_keep_mode_cmd);
+ install_element(GBPROXY_NODE, &cfg_gbproxy_link_stored_msgs_max_len_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mcc_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_no_core_mnc_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_no_match_imsi_cmd);
@@ -834,6 +859,7 @@ int gbproxy_vty_init(void)
install_element(GBPROXY_NODE, &cfg_gbproxy_no_acquire_imsi_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_age_cmd);
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_len_cmd);
+ install_element(GBPROXY_NODE, &cfg_gbproxy_link_no_stored_msgs_max_len_cmd);
/* broken or deprecated to allow an upgrade path */
install_element(GBPROXY_NODE, &cfg_gbproxy_broken_apn_match_cmd);