aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPravin Kumarvel <pmanohar@radisys.com>2016-12-29 20:23:15 +0530
committerPravin Kumarvel <pmanohar@radisys.com>2016-12-29 20:23:15 +0530
commitf595a4eadb340b225f2308fd1c33b8760958f365 (patch)
tree3d6730dfe5a2b26d2b4d9c68330227705c30bfbb
parentac82ca15e631c6e75f1935422434a89f59356ecd (diff)
Update README with working commit versions for openbsc.
Necessary changes for enabling new feature in openbsc.
-rw-r--r--README4
-rw-r--r--contrib/0001-Support-Deactivate-PDP-Context-Request-from-network.patch259
-rw-r--r--contrib/0002-Trigger-Deactivate-PDP-context-Request-from-SGSN-VTY.patch49
3 files changed, 312 insertions, 0 deletions
diff --git a/README b/README
index 1b3e1da..cc89ad6 100644
--- a/README
+++ b/README
@@ -9,6 +9,10 @@ This PCU enables
* Support for EPDAN
* Support for PUAN with CRBB
+Feature support for Deactivate PDP context Request from SGSN VTY.
+which has two patches are present in contrib has to be
+applied on top of openbsc 80abe522e2ddc979d994530f21b103808fc465d7.
+
== Current limitations ==
* No PFC support
diff --git a/contrib/0001-Support-Deactivate-PDP-Context-Request-from-network.patch b/contrib/0001-Support-Deactivate-PDP-Context-Request-from-network.patch
new file mode 100644
index 0000000..a94bd48
--- /dev/null
+++ b/contrib/0001-Support-Deactivate-PDP-Context-Request-from-network.patch
@@ -0,0 +1,259 @@
+From 4ce4f62ae647a8ff852f29815011186f15ee1d16 Mon Sep 17 00:00:00 2001
+From: Pravin Kumarvel <pmanohar@radisys.com>
+Date: Thu, 29 Dec 2016 20:17:14 +0530
+Subject: [PATCH 1/2] Support Deactivate PDP Context Request from network
+
+Enable Deactivate PDP context based on the IMSI of the subscriber.
+When there are PDP contexts present for a MM context,
+PDP context will be deactivated along with GMM Detach(MM context deletion).
+If there are no PDP present, MM context will be deleted to avoid
+further PDP context request from the MS.
+Test cases is added to check this functionality.
+---
+ openbsc/include/openbsc/gprs_sgsn.h | 2 +
+ openbsc/src/gprs/gprs_sgsn.c | 36 ++++++++++
+ openbsc/tests/sgsn/sgsn_test.c | 132 ++++++++++++++++++++++++++++++++++++
+ openbsc/tests/sgsn/sgsn_test.ok | 4 ++
+ 4 files changed, 174 insertions(+)
+
+diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
+index 24e286c..b3f250d 100644
+--- a/openbsc/include/openbsc/gprs_sgsn.h
++++ b/openbsc/include/openbsc/gprs_sgsn.h
+@@ -369,6 +369,8 @@ void sgsn_inst_init(void);
+ * ottherwise lost state (recovery procedure) */
+ int drop_all_pdp_for_ggsn(struct sgsn_ggsn_ctx *ggsn);
+
++void drop_gmm_ctx_for_ms(const char *imsi);
++
+ char *gprs_pdpaddr2str(uint8_t *pdpa, uint8_t len);
+
+ /*
+diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c
+index e85e1a9..94fcd5f 100644
+--- a/openbsc/src/gprs/gprs_sgsn.c
++++ b/openbsc/src/gprs/gprs_sgsn.c
+@@ -669,6 +669,42 @@ static void drop_one_pdp(struct sgsn_pdp_ctx *pdp)
+ }
+ }
+
++/*
++ * High-level function to be called for PDP deactivation initiated from SGSN VTY.
++ * When there are PDP contexts present for a MM context, PDP context will be
++ * deactivated along with GMM Detach(MM context deletion).
++ * If there are no PDP present, MM context will be deleted to avoid further
++ * PDP context activation for that MS.
++ */
++void drop_gmm_ctx_for_ms(const char *imsi)
++{
++ OSMO_ASSERT(imsi != NULL);
++ struct sgsn_mm_ctx *mm;
++ struct sgsn_pdp_ctx *pdp;
++
++ /* Search the MM context subscriber */
++ mm = sgsn_mm_ctx_by_imsi(imsi);
++ LOGMMCTXP(LOGL_INFO, mm, "SGSN intiated Deactivate PDP request\n");
++ if (mm) {
++ /* Search the PDP for this subscriber */
++ if (llist_empty(&mm->pdp_list)) {
++ /*
++ * Deleting mm context for the subscriber when no PDP
++ * context is present.
++ */
++ LOGMMCTXP(LOGL_NOTICE, mm, "No PDP context to deactivate\n");
++ gsm0408_gprs_access_cancelled(mm, GMM_CAUSE_GPRS_NOTALLOWED);
++ } else {
++ llist_for_each_entry(pdp, &mm->pdp_list, list) {
++ gsm48_tx_gsm_deact_pdp_req(pdp, GSM_CAUSE_DEACT_REGULAR);
++ LOGPDPCTXP(LOGL_INFO, pdp, "PDP Deactivation "
++ "Successful\n");
++ }
++ }
++ } else
++ LOGMMCTXP(LOGL_NOTICE, mm, "No MM context to deactivate\n");
++}
++
+ /* High-level function to be called in case a GGSN has disappeared or
+ * otherwise lost state (recovery procedure) */
+ int drop_all_pdp_for_ggsn(struct sgsn_ggsn_ctx *ggsn)
+diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c
+index b4bcaf6..f8bf186 100644
+--- a/openbsc/tests/sgsn/sgsn_test.c
++++ b/openbsc/tests/sgsn/sgsn_test.c
+@@ -38,14 +38,17 @@
+ #include <osmocom/core/rate_ctr.h>
+
+ #include <stdio.h>
++#include <gtp.h>
+
+ void *tall_bsc_ctx;
++struct gsn_t gsn_ctx;
+ static struct sgsn_instance sgsn_inst = {
+ .config_file = "osmo_sgsn.cfg",
+ .cfg = {
+ .gtp_statedir = "./",
+ .auth_policy = SGSN_AUTH_POLICY_CLOSED,
+ },
++ .gsn = &gsn_ctx,
+ };
+ struct sgsn_instance *sgsn = &sgsn_inst;
+ unsigned sgsn_tx_counter = 0;
+@@ -2363,6 +2366,134 @@ static void test_ggsn_selection(void)
+ cleanup_test();
+ }
+
++static void test_pdp_deactivation_with_pdp_ctx(void)
++{
++ struct apn_ctx *actxs[4];
++ struct sgsn_ggsn_ctx *ggc, *ggcs[3];
++ struct gsm_subscriber *s1;
++ const char *imsi1 = "12345678901";
++ struct sgsn_mm_ctx *ctx;
++ struct gprs_ra_id raid = { 0, };
++ uint32_t local_tlli = 0xffeeddcc;
++ enum gsm48_gsm_cause gsm_cause;
++ struct tlv_parsed tp;
++ uint8_t apn_enc[GSM_APN_LENGTH + 10];
++ struct sgsn_subscriber_pdp_data *pdp_data;
++ char apn_str[GSM_APN_LENGTH];
++
++ printf("Testing Pdp deactivation for MS with pdp ctx\n");
++
++ /* Check for emptiness */
++ OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
++
++ /* Create a context */
++ OSMO_ASSERT(count(gprs_llme_list()) == 0);
++ ctx = alloc_mm_ctx(local_tlli, &raid);
++ strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
++
++ /* Allocate and attach a subscriber */
++ s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
++ assert_subscr(s1, imsi1);
++
++ struct sgsn_pdp_ctx *pdp;
++
++ tp.lv[GSM48_IE_GSM_APN].len = 0;
++ tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
++
++ tp.lv[OSMO_IE_GSM_REQ_PDP_ADDR].len = 2;
++ tp.lv[OSMO_IE_GSM_REQ_PDP_ADDR].val = apn_enc;
++
++ tp.lv[OSMO_IE_GSM_REQ_QOS].len = 14;
++ tp.lv[OSMO_IE_GSM_REQ_QOS].val = apn_enc;
++
++ ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
++
++ actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
++ actxs[0]->ggsn = ggcs[0];
++
++ pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
++ pdp_data->context_id = 1;
++ pdp_data->pdp_type = 0x0121;
++ strncpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str)-1);
++
++ /* Resolve GGSNs */
++ tp.lv[GSM48_IE_GSM_APN].len =
++ gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
++
++ ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
++
++ OSMO_ASSERT(ggc != NULL);
++ OSMO_ASSERT(ggc->id == 0);
++
++ ggc = sgsn_ggsn_ctx_alloc(ggc->id);
++ /* Create a pdp context */
++ pdp = sgsn_create_pdp_ctx(ggc, ctx, 5, &tp);
++
++ /* Intiate PDP deactivation for imsi1 */
++ drop_gmm_ctx_for_ms(imsi1);
++ gsm48_tx_gsm_deact_pdp_acc(pdp);
++ gsm0408_gprs_access_cancelled(ctx, GMM_CAUSE_GPRS_NOTALLOWED);
++
++ /* Cleanup */
++
++ subscr_put(s1);
++
++ sgsn_apn_ctx_free(actxs[0]);
++ sgsn_ggsn_ctx_free(ggcs[0]);
++ sgsn_ggsn_ctx_free(ggc);
++ talloc_free(pdp);
++
++ cleanup_test();
++}
++
++static void test_pdp_deactivation_with_only_mm_ctx(void)
++{
++ struct gsm_subscriber *s1;
++ const char *imsi1 = "1234567890";
++ struct sgsn_mm_ctx *ctx;
++ struct gprs_ra_id raid = { 0, };
++ uint32_t local_tlli = 0xffeeddcc;
++
++ printf("Testing Pdp deactivation for MS with only MM ctx\n");
++
++ /* Check for emptiness */
++ OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
++
++ /* Create a context */
++ OSMO_ASSERT(count(gprs_llme_list()) == 0);
++ ctx = alloc_mm_ctx(local_tlli, &raid);
++ strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
++
++ /* Allocate and attach a subscriber */
++ s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
++ assert_subscr(s1, imsi1);
++
++ /* Intiate PDP deactivation for imsi1 */
++ drop_gmm_ctx_for_ms(imsi1);
++
++ cleanup_test();
++}
++
++static void test_pdp_deactivation_without_mm_ctx(void)
++{
++ const char *imsi1 = "1234567890";
++
++ printf("Testing Pdp deactivation for MS without MM ctx\n");
++
++ /* Intiate PDP deactivation for imsi1 */
++ drop_gmm_ctx_for_ms(imsi1);
++
++ cleanup_test();
++}
++
++static void test_pdp_deactivation(void)
++{
++ printf("Testing pdp deactivation\n");
++
++ test_pdp_deactivation_with_only_mm_ctx();
++ test_pdp_deactivation_with_pdp_ctx();
++ test_pdp_deactivation_without_mm_ctx();
++}
+ static struct log_info_cat gprs_categories[] = {
+ [DMM] = {
+ .name = "DMM",
+@@ -2454,6 +2585,7 @@ int main(int argc, char **argv)
+ test_gmm_routing_areas();
+ test_apn_matching();
+ test_ggsn_selection();
++ test_pdp_deactivation();
+ printf("Done\n");
+
+ talloc_report_full(osmo_sgsn_ctx, stderr);
+diff --git a/openbsc/tests/sgsn/sgsn_test.ok b/openbsc/tests/sgsn/sgsn_test.ok
+index c7a53b9..6159bc9 100644
+--- a/openbsc/tests/sgsn/sgsn_test.ok
++++ b/openbsc/tests/sgsn/sgsn_test.ok
+@@ -34,4 +34,8 @@ Testing routing area changes
+ - RA Update Request (RA 2 -> RA 2)
+ Testing APN matching
+ Testing GGSN selection
++Testing pdp deactivation
++Testing Pdp deactivation for MS with only MM ctx
++Testing Pdp deactivation for MS with pdp ctx
++Testing Pdp deactivation for MS without MM ctx
+ Done
+--
+1.9.1
+
diff --git a/contrib/0002-Trigger-Deactivate-PDP-context-Request-from-SGSN-VTY.patch b/contrib/0002-Trigger-Deactivate-PDP-context-Request-from-SGSN-VTY.patch
new file mode 100644
index 0000000..1b72bb6
--- /dev/null
+++ b/contrib/0002-Trigger-Deactivate-PDP-context-Request-from-SGSN-VTY.patch
@@ -0,0 +1,49 @@
+From 29f7bd1023fc698ebdb19b93f8029b2559392f17 Mon Sep 17 00:00:00 2001
+From: Pravin Kumarvel <pmanohar@radisys.com>
+Date: Thu, 29 Dec 2016 20:18:49 +0530
+Subject: [PATCH 2/2] Trigger Deactivate PDP context Request from SGSN VTY
+
+In SGSN for acl based authorization IMSI values of all registered
+MS are maintained.
+Through imsi_acl_del Deactivate PDP context Request from network
+can be triggered.
+Hence, It will remove all PDP context related to that MS.
+---
+ openbsc/src/gprs/gprs_gmm.c | 2 ++
+ openbsc/src/gprs/sgsn_vty.c | 6 ++++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
+index 363b457..77f94f8 100644
+--- a/openbsc/src/gprs/gprs_gmm.c
++++ b/openbsc/src/gprs/gprs_gmm.c
+@@ -2535,6 +2535,8 @@ static int gsm0408_rcv_gsm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
+ break;
+ case GSM48_MT_GSM_DEACT_PDP_ACK:
+ rc = gsm48_rx_gsm_deact_pdp_ack(mmctx, msg);
++ if (sgsn_auth_state(mmctx) != SGSN_AUTH_ACCEPTED)
++ gsm0408_gprs_access_cancelled(mmctx, GMM_CAUSE_GPRS_NOTALLOWED);
+ break;
+ case GSM48_MT_GSM_STATUS:
+ rc = gsm48_rx_gsm_status(mmctx, msg);
+diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c
+index 21c865b..feeb0ff 100644
+--- a/openbsc/src/gprs/sgsn_vty.c
++++ b/openbsc/src/gprs/sgsn_vty.c
+@@ -573,9 +573,11 @@ DEFUN(imsi_acl, cfg_imsi_acl_cmd,
+
+ if (!strcmp(op, "add"))
+ rc = sgsn_acl_add(imsi, g_cfg);
+- else
++ else {
++ vty_out(vty, "%% Network initiated PDP deactivate%s", VTY_NEWLINE);
++ drop_gmm_ctx_for_ms(imsi);
+ rc = sgsn_acl_del(imsi, g_cfg);
+-
++ }
+ if (rc < 0) {
+ vty_out(vty, "%% unable to %s ACL%s", op, VTY_NEWLINE);
+
+--
+1.9.1
+