diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-10-02 21:27:24 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-10-09 17:22:34 +0200 |
commit | 4299c0560ffba27254ce98853e0cc249f5024353 (patch) | |
tree | 82cd46fe3390a2c44884dfae6575aaa23be25e52 | |
parent | 68c6f887c222bf9527fe3960285608f12071e81f (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.h | 6 | ||||
-rw-r--r-- | openbsc/src/gprs/gprs_llc.c | 36 | ||||
-rw-r--r-- | openbsc/tests/sgsn/Makefile.am | 14 | ||||
-rw-r--r-- | openbsc/tests/sgsn/sgsn_test.c | 135 | ||||
-rw-r--r-- | openbsc/tests/sgsn/sgsn_test.ok | 2 |
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 |