aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-09-25 11:17:31 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-10-09 18:02:33 +0200
commit9a83d7af55772e4e2e6f187ab11d3f2a2665791c (patch)
treeb57ec27fd26bba90c88252251c5249bafd4d85d1 /openbsc/src/gprs
parent55ec2bf97f9b30ea44c05e1ec5310bf93cee7884 (diff)
gbproxy: Refactor IMSI matching
The current implementation makes it difficult to add further match expressions. This patch adds a new struct gbproxy_match that contains the fields needed for each match expression. The matches (config) and the results (link_info) are stored in arrays. All related functions are updated to use them. The old fields in the config structure are removed. Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src/gprs')
-rw-r--r--openbsc/src/gprs/gb_proxy.c5
-rw-r--r--openbsc/src/gprs/gb_proxy_patch.c38
-rw-r--r--openbsc/src/gprs/gb_proxy_tlli.c28
-rw-r--r--openbsc/src/gprs/gb_proxy_vty.c22
4 files changed, 58 insertions, 35 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 3257f7490..41ff4a785 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -584,7 +584,8 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
if (link_info && cfg->route_to_sgsn2) {
if (cfg->acquire_imsi && link_info->imsi_len == 0)
sgsn_nsei = 0xffff;
- else if (gbproxy_imsi_matches(peer, link_info))
+ else if (gbproxy_imsi_matches(cfg, GBPROX_MATCH_PATCHING,
+ link_info))
sgsn_nsei = cfg->nsip_sgsn2_nsei;
}
@@ -1346,10 +1347,12 @@ void gbprox_reset(struct gbproxy_config *cfg)
int gbproxy_init_config(struct gbproxy_config *cfg)
{
struct timespec tp;
+
INIT_LLIST_HEAD(&cfg->bts_peers);
cfg->ctrg = rate_ctr_group_alloc(tall_bsc_ctx, &global_ctrg_desc, 0);
clock_gettime(CLOCK_REALTIME, &tp);
cfg->bss_ptmsi_state = tp.tv_sec + tp.tv_nsec;
cfg->sgsn_tlli_state = tp.tv_sec - tp.tv_nsec;
+
return 0;
}
diff --git a/openbsc/src/gprs/gb_proxy_patch.c b/openbsc/src/gprs/gb_proxy_patch.c
index cf6eb8887..5cac8a5d8 100644
--- a/openbsc/src/gprs/gb_proxy_patch.c
+++ b/openbsc/src/gprs/gb_proxy_patch.c
@@ -24,6 +24,7 @@
#include <openbsc/gprs_gb_parse.h>
#include <openbsc/gsm_04_08_gprs.h>
+#include <openbsc/gsm_data.h>
#include <openbsc/debug.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
@@ -198,6 +199,7 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
struct gprs_llc_hdr_parsed *ghp = &parse_ctx->llc_hdr_parsed;
int have_patched = 0;
int fcs;
+ struct gbproxy_config *cfg = peer->cfg;
if (parse_ctx->ptmsi_enc && link_info &&
!parse_ctx->old_raid_is_foreign && peer->cfg->patch_ptmsi) {
@@ -216,7 +218,7 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
}
}
- if (parse_ctx->new_ptmsi_enc && link_info && peer->cfg->patch_ptmsi) {
+ if (parse_ctx->new_ptmsi_enc && link_info && cfg->patch_ptmsi) {
uint32_t ptmsi;
if (parse_ctx->to_bss)
ptmsi = link_info->tlli.ptmsi;
@@ -243,9 +245,10 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
}
if (parse_ctx->apn_ie &&
- peer->cfg->core_apn &&
+ cfg->core_apn &&
!parse_ctx->to_bss &&
- gbproxy_imsi_matches(peer, link_info) && peer->cfg->core_apn) {
+ gbproxy_imsi_matches(cfg, GBPROX_MATCH_PATCHING, link_info) &&
+ cfg->core_apn) {
size_t new_len;
gbproxy_patch_apn_ie(msg,
parse_ctx->apn_ie, parse_ctx->apn_ie_len,
@@ -371,35 +374,38 @@ patch_error:
err_info);
}
-void gbproxy_clear_patch_filter(struct gbproxy_config *cfg)
+void gbproxy_clear_patch_filter(struct gbproxy_match *match)
{
- if (cfg->check_imsi) {
- regfree(&cfg->imsi_re_comp);
- cfg->check_imsi = 0;
+ if (match->enable) {
+ regfree(&match->re_comp);
+ match->enable = 0;
}
+ talloc_free(match->re_str);
+ match->re_str = NULL;
}
-int gbproxy_set_patch_filter(struct gbproxy_config *cfg, const char *filter,
+int gbproxy_set_patch_filter(struct gbproxy_match *match, const char *filter,
const char **err_msg)
{
static char err_buf[300];
int rc;
- gbproxy_clear_patch_filter(cfg);
+ gbproxy_clear_patch_filter(match);
if (!filter)
return 0;
- rc = regcomp(&cfg->imsi_re_comp, filter,
+ rc = regcomp(&match->re_comp, filter,
REG_EXTENDED | REG_NOSUB | REG_ICASE);
if (rc == 0) {
- cfg->check_imsi = 1;
+ match->enable = 1;
+ match->re_str = talloc_strdup(tall_bsc_ctx, filter);
return 0;
}
if (err_msg) {
- regerror(rc, &cfg->imsi_re_comp,
+ regerror(rc, &match->re_comp,
err_buf, sizeof(err_buf));
*err_msg = err_buf;
}
@@ -407,13 +413,13 @@ int gbproxy_set_patch_filter(struct gbproxy_config *cfg, const char *filter,
return -1;
}
-int gbproxy_check_imsi(struct gbproxy_peer *peer,
+int gbproxy_check_imsi(struct gbproxy_match *match,
const uint8_t *imsi, size_t imsi_len)
{
char mi_buf[200];
int rc;
- if (!peer->cfg->check_imsi)
+ if (!match->enable)
return 1;
rc = gprs_is_mi_imsi(imsi, imsi_len);
@@ -427,11 +433,11 @@ int gbproxy_check_imsi(struct gbproxy_peer *peer,
LOGP(DGPRS, LOGL_DEBUG, "Checking IMSI '%s' (%d)\n", mi_buf, rc);
- rc = regexec(&peer->cfg->imsi_re_comp, mi_buf, 0, NULL, 0);
+ rc = regexec(&match->re_comp, mi_buf, 0, NULL, 0);
if (rc == REG_NOMATCH) {
LOGP(DGPRS, LOGL_INFO,
"IMSI '%s' doesn't match pattern '%s'\n",
- mi_buf, peer->cfg->match_re);
+ mi_buf, match->re_str);
return 0;
}
diff --git a/openbsc/src/gprs/gb_proxy_tlli.c b/openbsc/src/gprs/gb_proxy_tlli.c
index 093d2b328..d521434da 100644
--- a/openbsc/src/gprs/gb_proxy_tlli.c
+++ b/openbsc/src/gprs/gb_proxy_tlli.c
@@ -374,13 +374,18 @@ static void gbproxy_unregister_link_info(struct gbproxy_peer *peer,
return;
}
-int gbproxy_imsi_matches(struct gbproxy_peer *peer,
- struct gbproxy_link_info *link_info)
+int gbproxy_imsi_matches(struct gbproxy_config *cfg,
+ enum gbproxy_match_id match_id,
+ struct gbproxy_link_info *link_info)
{
- if (!peer->cfg->check_imsi)
+ struct gbproxy_match *match;
+ OSMO_ASSERT(match_id >= 0 && match_id < ARRAY_SIZE(cfg->matches));
+
+ match = &cfg->matches[match_id];
+ if (!match->enable)
return 1;
- return link_info != NULL && link_info->imsi_matches;
+ return link_info != NULL && link_info->is_matching[match_id];
}
void gbproxy_assign_imsi(struct gbproxy_peer *peer,
@@ -389,6 +394,7 @@ void gbproxy_assign_imsi(struct gbproxy_peer *peer,
{
int imsi_matches;
struct gbproxy_link_info *other_link_info;
+ enum gbproxy_match_id match_id;
/* Make sure that there is a second entry with the same IMSI */
other_link_info = gbproxy_link_info_by_imsi(
@@ -410,10 +416,16 @@ void gbproxy_assign_imsi(struct gbproxy_peer *peer,
parse_ctx->imsi, parse_ctx->imsi_len);
/* Check, whether the IMSI matches */
- imsi_matches = gbproxy_check_imsi(peer, parse_ctx->imsi,
- parse_ctx->imsi_len);
- if (imsi_matches >= 0)
- link_info->imsi_matches = imsi_matches;
+ OSMO_ASSERT(ARRAY_SIZE(link_info->is_matching) ==
+ ARRAY_SIZE(peer->cfg->matches));
+ for (match_id = 0; match_id < ARRAY_SIZE(link_info->is_matching);
+ ++match_id) {
+ imsi_matches = gbproxy_check_imsi(
+ &peer->cfg->matches[match_id],
+ parse_ctx->imsi, parse_ctx->imsi_len);
+ if (imsi_matches >= 0)
+ link_info->is_matching[match_id] = imsi_matches;
+ }
}
static int gbproxy_tlli_match(const struct gbproxy_tlli_state *a,
diff --git a/openbsc/src/gprs/gb_proxy_vty.c b/openbsc/src/gprs/gb_proxy_vty.c
index 82d7d9541..6dc0e3437 100644
--- a/openbsc/src/gprs/gb_proxy_vty.c
+++ b/openbsc/src/gprs/gb_proxy_vty.c
@@ -75,6 +75,8 @@ static void gbprox_vty_print_peer(struct vty *vty, struct gbproxy_peer *peer)
static int config_write_gbproxy(struct vty *vty)
{
+ enum gbproxy_match_id match_id;
+
vty_out(vty, "gbproxy%s", VTY_NEWLINE);
vty_out(vty, " sgsn nsei %u%s", g_cfg->nsip_sgsn_nsei,
@@ -87,9 +89,12 @@ static int config_write_gbproxy(struct vty *vty)
vty_out(vty, " core-mobile-network-code %d%s",
g_cfg->core_mnc, VTY_NEWLINE);
- if (g_cfg->match_re)
- vty_out(vty, " match-imsi %s%s",
- g_cfg->match_re, VTY_NEWLINE);
+ for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id) {
+ struct gbproxy_match *match = &g_cfg->matches[match_id];
+ if (match->re_str)
+ vty_out(vty, " match-imsi %s%s",
+ match->re_str, VTY_NEWLINE);
+ }
if (g_cfg->core_apn != NULL) {
if (g_cfg->core_apn_size > 0) {
@@ -194,15 +199,13 @@ DEFUN(cfg_gbproxy_match_imsi,
{
const char *filter = argv[0];
const char *err_msg = NULL;
+ struct gbproxy_match *match = &g_cfg->matches[GBPROX_MATCH_PATCHING];
- if (gbproxy_set_patch_filter(g_cfg, filter, &err_msg) != 0) {
+ if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) {
vty_out(vty, "Match expression invalid: %s%s",
err_msg, VTY_NEWLINE);
return CMD_WARNING;
}
- talloc_free(g_cfg->match_re);
- /* TODO: replace NULL */
- g_cfg->match_re = talloc_strdup(NULL, filter);
g_cfg->acquire_imsi = 1;
@@ -214,10 +217,9 @@ DEFUN(cfg_gbproxy_no_match_imsi,
"no match-imsi",
NO_STR GBPROXY_MATCH_IMSI_STR)
{
- gbproxy_clear_patch_filter(g_cfg);
+ struct gbproxy_match *match = &g_cfg->matches[GBPROX_MATCH_PATCHING];
- talloc_free(g_cfg->match_re);
- g_cfg->match_re = NULL;
+ gbproxy_clear_patch_filter(match);
g_cfg->acquire_imsi = 0;