aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-11-07 14:17:44 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-11-14 10:23:54 +0100
commitf951a01bb227e524eb369051c95fbebace7570d0 (patch)
tree9a01dc28a3675f95e4b43ab70e05da8a25eb442f
parentf6e7d99d54cc75fdc19433011afb5eaaa8a2a002 (diff)
sgsn: Refactor sgsn_auth to separate request and authorization
Currently the authorization is done in sgsn_auth_request for ACL based authorization. This doesn't match the way remote authorization would work, so that there is a second call to sgsn_auth_state already present in sgsn_auth_update. This patch removes the autorization check completely from sgsn_auth_request which in turn calls sgsn_auth_update directly now. Sponsored-by: On-Waves ehf
-rw-r--r--openbsc/include/openbsc/gprs_sgsn.h6
-rw-r--r--openbsc/src/gprs/gprs_gmm.c2
-rw-r--r--openbsc/src/gprs/gprs_sgsn.c6
-rw-r--r--openbsc/src/gprs/sgsn_auth.c38
4 files changed, 30 insertions, 22 deletions
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
index 0cb722067..ac78a1626 100644
--- a/openbsc/include/openbsc/gprs_sgsn.h
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -269,6 +269,7 @@ struct sgsn_subscriber_data {
struct sgsn_config;
struct sgsn_instance;
+extern const struct value_string *sgsn_auth_state_names;
void sgsn_auth_init(struct sgsn_instance *sgi);
struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, struct sgsn_config *cfg);
@@ -278,11 +279,10 @@ int sgsn_acl_del(const char *imsi, struct sgsn_config *cfg);
int sgsn_auth_request(struct sgsn_mm_ctx *mm, struct sgsn_config *cfg);
enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mm,
struct sgsn_config *cfg);
-void sgsn_auth_update(struct sgsn_mm_ctx *mm, struct sgsn_subscriber_data *sd);
+void sgsn_auth_update(struct sgsn_mm_ctx *mm, struct sgsn_instance *sgi);
/* Called on subscriber data updates */
-void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
- struct sgsn_subscriber_data *sd);
+void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx);
int gprs_sndcp_vty_init(void);
struct sgsn_instance;
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index afd3bbb06..48fb29d1b 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -644,7 +644,7 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx)
if (ctx->auth_state == SGSN_AUTH_UNKNOWN) {
/* Request authorization, this leads to a call to
- * sgsn_update_subscriber_data which in turn calls
+ * sgsn_auth_update which in turn calls
* gsm0408_gprs_access_granted or gsm0408_gprs_access_denied */
sgsn_auth_request(ctx, &sgsn->cfg);
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c
index daf9483bd..9fc4b86f3 100644
--- a/openbsc/src/gprs/gprs_sgsn.c
+++ b/openbsc/src/gprs/gprs_sgsn.c
@@ -451,11 +451,9 @@ int sgsn_force_reattach_oldmsg(struct msgb *oldmsg)
return gsm0408_gprs_force_reattach_oldmsg(oldmsg);
}
-void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
- struct sgsn_subscriber_data *sd)
+void sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
{
OSMO_ASSERT(mmctx);
- if (sd->auth_state != mmctx->auth_state)
- sgsn_auth_update(mmctx, sd);
+ sgsn_auth_update(mmctx, sgsn);
}
diff --git a/openbsc/src/gprs/sgsn_auth.c b/openbsc/src/gprs/sgsn_auth.c
index d2d4913b6..0407e9e69 100644
--- a/openbsc/src/gprs/sgsn_auth.c
+++ b/openbsc/src/gprs/sgsn_auth.c
@@ -32,6 +32,8 @@ const struct value_string auth_state_names[] = {
{ 0, NULL }
};
+const struct value_string *sgsn_auth_state_names = auth_state_names;
+
void sgsn_auth_init(struct sgsn_instance *sgi)
{
INIT_LLIST_HEAD(&sgi->cfg.imsi_acl);
@@ -125,29 +127,37 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx,
int sgsn_auth_request(struct sgsn_mm_ctx *mmctx, struct sgsn_config *cfg)
{
- struct sgsn_subscriber_data sd = {0};
+ /* TODO: Add remote subscriber update requests here */
+
+ sgsn_auth_update(mmctx, sgsn);
+
+ return 0;
+}
+
+void sgsn_auth_update(struct sgsn_mm_ctx *mmctx, struct sgsn_instance *sgi)
+{
+ enum sgsn_auth_state auth_state;
- sd.auth_state = sgsn_auth_state(mmctx, cfg);
+ LOGMMCTXP(LOGL_DEBUG, mmctx, "Updating authorization\n");
- if (sd.auth_state == SGSN_AUTH_UNKNOWN) {
+ auth_state = sgsn_auth_state(mmctx, &sgi->cfg);
+ if (auth_state == SGSN_AUTH_UNKNOWN) {
+ /* Reject requests since remote updates are NYI */
LOGMMCTXP(LOGL_ERROR, mmctx,
"Missing information, authorization not possible\n");
- sd.auth_state = SGSN_AUTH_REJECTED;
+ auth_state = SGSN_AUTH_REJECTED;
}
- /* This will call sgsn_auth_update if auth_state has changed */
- sgsn_update_subscriber_data(mmctx, &sd);
- return 0;
-}
+ if (mmctx->auth_state == auth_state)
+ return;
-void sgsn_auth_update(struct sgsn_mm_ctx *mmctx, struct sgsn_subscriber_data *sd)
-{
- LOGMMCTXP(LOGL_INFO, mmctx, "Got authorization update: state %s\n",
- get_value_string(auth_state_names, sd->auth_state));
+ LOGMMCTXP(LOGL_INFO, mmctx, "Got authorization update: state %s -> %s\n",
+ get_value_string(sgsn_auth_state_names, mmctx->auth_state),
+ get_value_string(sgsn_auth_state_names, auth_state));
- mmctx->auth_state = sd->auth_state;
+ mmctx->auth_state = auth_state;
- switch (sd->auth_state) {
+ switch (auth_state) {
case SGSN_AUTH_ACCEPTED:
gsm0408_gprs_access_granted(mmctx);
break;