aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-10-02 21:27:24 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-10-09 17:22:34 +0200
commit4299c0560ffba27254ce98853e0cc249f5024353 (patch)
tree82cd46fe3390a2c44884dfae6575aaa23be25e52
parent68c6f887c222bf9527fe3960285608f12071e81f (diff)
sgsn: Create testcase that verifies that llmes get deleted
On an "unassignment" this code verifies that the LLME will vanish from the list of LLMEs. We assume that this doesn't create a memory leak.
-rw-r--r--openbsc/include/openbsc/gprs_llc.h6
-rw-r--r--openbsc/src/gprs/gprs_llc.c36
-rw-r--r--openbsc/tests/sgsn/Makefile.am14
-rw-r--r--openbsc/tests/sgsn/sgsn_test.c135
-rw-r--r--openbsc/tests/sgsn/sgsn_test.ok2
5 files changed, 182 insertions, 11 deletions
diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h
index 854b9688a..9689a3766 100644
--- a/openbsc/include/openbsc/gprs_llc.h
+++ b/openbsc/include/openbsc/gprs_llc.h
@@ -240,4 +240,10 @@ int gprs_llc_hdr_parse(struct gprs_llc_hdr_parsed *ghp,
void gprs_llc_hdr_dump(struct gprs_llc_hdr_parsed *gph);
int gprs_llc_fcs(uint8_t *data, unsigned int len);
+
+/* LLME handling routines */
+struct llist_head *gprs_llme_list(void);
+struct gprs_llc_lle *gprs_lle_get_or_create(const uint32_t tlli, uint8_t sapi);
+
+
#endif
diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c
index b157bfda8..cb810c4a2 100644
--- a/openbsc/src/gprs/gprs_llc.c
+++ b/openbsc/src/gprs/gprs_llc.c
@@ -166,6 +166,31 @@ static struct gprs_llc_lle *lle_by_tlli_sapi(const uint32_t tlli, uint8_t sapi)
return NULL;
}
+struct gprs_llc_lle *gprs_lle_get_or_create(const uint32_t tlli, uint8_t sapi)
+{
+ struct gprs_llc_llme *llme;
+ struct gprs_llc_lle *lle;
+
+ lle = lle_by_tlli_sapi(tlli, sapi);
+ if (lle)
+ return lle;
+
+ lle = lle_by_tlli_sapi(tlli_foreign2local(tlli), sapi);
+ if (lle)
+ return lle;
+
+ LOGP(DLLC, LOGL_NOTICE, "LLC: unknown TLLI 0x%08x, "
+ "creating LLME on the fly\n", tlli);
+ llme = llme_alloc(tlli);
+ lle = &llme->lle[sapi];
+ return lle;
+}
+
+struct llist_head *gprs_llme_list(void)
+{
+ return &gprs_llc_llmes;
+}
+
/* lookup LLC Entity for RX based on DLCI (TLLI+SAPI tuple) */
static struct gprs_llc_lle *lle_for_rx_by_tlli_sapi(const uint32_t tlli,
uint8_t sapi, enum gprs_llc_cmd cmd)
@@ -352,16 +377,7 @@ int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command,
/* Identifiers from UP: (TLLI, SAPI) + (BVCI, NSEI) */
/* look-up or create the LL Entity for this (TLLI, SAPI) tuple */
- lle = lle_by_tlli_sapi(msgb_tlli(msg), sapi);
- if (!lle)
- lle = lle_by_tlli_sapi(tlli_foreign2local(msgb_tlli(msg)), sapi);
- if (!lle) {
- struct gprs_llc_llme *llme;
- LOGP(DLLC, LOGL_NOTICE, "LLC TX: unknown TLLI 0x%08x, "
- "creating LLME on the fly\n", msgb_tlli(msg));
- llme = llme_alloc(msgb_tlli(msg));
- lle = &llme->lle[sapi];
- }
+ lle = gprs_lle_get_or_create(msgb_tlli(msg), sapi);
if (msg->len > lle->params.n201_u) {
LOGP(DLLC, LOGL_ERROR, "Cannot Tx %u bytes (N201-U=%u)\n",
diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am
index 9753acfc9..af00a34a8 100644
--- a/openbsc/tests/sgsn/Makefile.am
+++ b/openbsc/tests/sgsn/Makefile.am
@@ -6,5 +6,17 @@ EXTRA_DIST = sgsn_test.ok
noinst_PROGRAMS = sgsn_test
sgsn_test_SOURCES = sgsn_test.c
-sgsn_test_LDADD = $(LIBOSMOCORE_LIBS)
+sgsn_test_LDADD = \
+ $(top_builddir)/src/gprs/gprs_llc_parse.o \
+ $(top_builddir)/src/gprs/gprs_llc.o \
+ $(top_builddir)/src/gprs/crc24.o \
+ $(top_builddir)/src/gprs/gprs_sndcp.o \
+ $(top_builddir)/src/gprs/gprs_gmm.o \
+ $(top_builddir)/src/gprs/gprs_sgsn.o \
+ $(top_builddir)/src/gprs/sgsn_vty.o \
+ $(top_builddir)/src/gprs/sgsn_libgtp.o \
+ $(LIBOSMOCORE_LIBS) \
+ $(LIBOSMOGSM_LIBS) \
+ $(LIBOSMOGB_LIBS) \
+ -lgtp
diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c
index 729cecd83..6224fd5e1 100644
--- a/openbsc/tests/sgsn/sgsn_test.c
+++ b/openbsc/tests/sgsn/sgsn_test.c
@@ -19,9 +19,144 @@
*
*/
+#include <openbsc/gprs_llc.h>
+#include <openbsc/sgsn.h>
+#include <openbsc/debug.h>
+
+#include <osmocom/gsm/gsm_utils.h>
+
+#include <osmocom/core/application.h>
+#include <osmocom/core/msgb.h>
+
#include <stdio.h>
+extern void *tall_msgb_ctx;
+
+void *tall_bsc_ctx;
+static struct sgsn_instance sgsn_inst = {
+ .config_file = "osmo_sgsn.cfg",
+ .cfg = {
+ .gtp_statedir = "./",
+ .acl_enabled = 1,
+ },
+};
+struct sgsn_instance *sgsn = &sgsn_inst;
+
+static int count(struct llist_head *head)
+{
+ struct llist_head *cur;
+ int count = 0;
+
+ llist_for_each(cur, head)
+ count += 1;
+
+ return count;
+}
+
+static void test_llme(void)
+{
+ struct gprs_llc_lle *lle, *lle_copy;
+ uint32_t local_tlli;
+ uint32_t foreign_tlli;
+
+ printf("Testing LLME allocations\n");
+ local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
+ foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
+
+ /* initial state */
+ OSMO_ASSERT(count(gprs_llme_list()) == 0);
+
+ /* Create a new entry */
+ lle = gprs_lle_get_or_create(local_tlli, 3);
+ OSMO_ASSERT(lle);
+ OSMO_ASSERT(count(gprs_llme_list()) == 1);
+
+ /* No new entry is created */
+ lle_copy = gprs_lle_get_or_create(local_tlli, 3);
+ OSMO_ASSERT(lle == lle_copy);
+ OSMO_ASSERT(count(gprs_llme_list()) == 1);
+ lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
+ OSMO_ASSERT(lle == lle_copy);
+ OSMO_ASSERT(count(gprs_llme_list()) == 1);
+
+ /* unassign which should delete it*/
+ gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
+
+ /* Check that everything was cleaned up */
+ OSMO_ASSERT(count(gprs_llme_list()) == 0);
+}
+
+
+static struct log_info_cat gprs_categories[] = {
+ [DMM] = {
+ .name = "DMM",
+ .description = "Layer3 Mobility Management (MM)",
+ .color = "\033[1;33m",
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ },
+ [DPAG] = {
+ .name = "DPAG",
+ .description = "Paging Subsystem",
+ .color = "\033[1;38m",
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ },
+ [DMEAS] = {
+ .name = "DMEAS",
+ .description = "Radio Measurement Processing",
+ .enabled = 0, .loglevel = LOGL_NOTICE,
+ },
+ [DREF] = {
+ .name = "DREF",
+ .description = "Reference Counting",
+ .enabled = 0, .loglevel = LOGL_NOTICE,
+ },
+ [DGPRS] = {
+ .name = "DGPRS",
+ .description = "GPRS Packet Service",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
+ [DNS] = {
+ .name = "DNS",
+ .description = "GPRS Network Service (NS)",
+ .enabled = 1, .loglevel = LOGL_INFO,
+ },
+ [DBSSGP] = {
+ .name = "DBSSGP",
+ .description = "GPRS BSS Gateway Protocol (BSSGP)",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
+ [DLLC] = {
+ .name = "DLLC",
+ .description = "GPRS Logical Link Control Protocol (LLC)",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
+ [DSNDCP] = {
+ .name = "DSNDCP",
+ .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
+};
+
+static struct log_info info = {
+ .cat = gprs_categories,
+ .num_cat = ARRAY_SIZE(gprs_categories),
+};
+
int main(int argc, char **argv)
{
+ osmo_init_logging(&info);
+ tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
+ tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
+
+ test_llme();
+ printf("Done\n");
return 0;
}
+
+
+/* stubs */
+struct osmo_prim_hdr;
+int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ abort();
+}
diff --git a/openbsc/tests/sgsn/sgsn_test.ok b/openbsc/tests/sgsn/sgsn_test.ok
index e69de29bb..045b9e534 100644
--- a/openbsc/tests/sgsn/sgsn_test.ok
+++ b/openbsc/tests/sgsn/sgsn_test.ok
@@ -0,0 +1,2 @@
+Testing LLME allocations
+Done