From 415cd2eebb5313f044612385e09d8b8af9cfe674 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 20 Jan 2014 09:55:46 +0100 Subject: [PATCH] nat: Introduce reject cause to bsc_nat_acc_lst_entry The filtering architecture already allowed to specify a reject reason but this has not been used for the access-lists. Extend the access-list to include a reject reason and extend the test case to honor it. --- openbsc/include/openbsc/bsc_nat.h | 4 + openbsc/src/osmo-bsc_nat/bsc_nat_filter.c | 16 +++- openbsc/src/osmo-bsc_nat/bsc_nat_utils.c | 2 + openbsc/tests/bsc-nat/bsc_nat_test.c | 103 +++++++++++++++++++++- 4 files changed, 120 insertions(+), 5 deletions(-) diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index 150979b10..fe8e52137 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -247,6 +247,10 @@ struct bsc_nat_acc_lst_entry { regex_t imsi_allow_re; char *imsi_deny; regex_t imsi_deny_re; + + /* reject reasons for the access lists */ + int cm_reject_cause; + int lu_reject_cause; }; /** diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_filter.c b/openbsc/src/osmo-bsc_nat/bsc_nat_filter.c index 8ccc26259..d29ea9c16 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_filter.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_filter.c @@ -122,15 +122,19 @@ int bsc_nat_barr_adapt(void *ctx, struct rb_root *root, } -static int lst_check_deny(struct bsc_nat_acc_lst *lst, const char *mi_string) +static int lst_check_deny(struct bsc_nat_acc_lst *lst, const char *mi_string, + int *cm_cause, int *lu_cause) { struct bsc_nat_acc_lst_entry *entry; llist_for_each_entry(entry, &lst->fltr_list, list) { if (!entry->imsi_deny) continue; - if (regexec(&entry->imsi_deny_re, mi_string, 0, NULL, 0) == 0) + if (regexec(&entry->imsi_deny_re, mi_string, 0, NULL, 0) == 0) { + *cm_cause = entry->cm_reject_cause; + *lu_cause = entry->lu_reject_cause; return 0; + } } return 1; @@ -173,10 +177,12 @@ static int auth_imsi(struct bsc_connection *bsc, const char *imsi, return 1; /* 3. BSC deny */ - if (lst_check_deny(bsc_lst, imsi) == 0) { + if (lst_check_deny(bsc_lst, imsi, &cm, &lu) == 0) { LOGP(DNAT, LOGL_ERROR, "Filtering %s by imsi_deny on bsc nr: %d.\n", imsi, bsc->cfg->nr); rate_ctr_inc(&bsc_lst->stats->ctr[ACC_LIST_BSC_FILTER]); + cause->cm_reject_cause = cm; + cause->lu_reject_cause = lu; return -2; } @@ -184,10 +190,12 @@ static int auth_imsi(struct bsc_connection *bsc, const char *imsi, /* 4. NAT deny */ if (nat_lst) { - if (lst_check_deny(nat_lst, imsi) == 0) { + if (lst_check_deny(nat_lst, imsi, &cm, &lu) == 0) { LOGP(DNAT, LOGL_ERROR, "Filtering %s by nat imsi_deny on bsc nr: %d.\n", imsi, bsc->cfg->nr); rate_ctr_inc(&nat_lst->stats->ctr[ACC_LIST_NAT_FILTER]); + cause->cm_reject_cause = cm; + cause->lu_reject_cause = lu; return -3; } } diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c index bc8c4c1f3..236a0fb05 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c @@ -468,6 +468,8 @@ struct bsc_nat_acc_lst_entry *bsc_nat_acc_lst_entry_create(struct bsc_nat_acc_ls if (!entry) return NULL; + entry->cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED; + entry->lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED; llist_add_tail(&entry->list, &lst->fltr_list); return entry; } diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index a121c8ab3..bed5b8079 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -696,6 +696,12 @@ struct cr_filter { const char *bsc_imsi_allow; const char *bsc_imsi_deny; const char *nat_imsi_deny; + int nat_cm_reject_cause; + int nat_lu_reject_cause; + int bsc_cm_reject_cause; + int bsc_lu_reject_cause; + int want_cm_reject_cause; + int want_lu_reject_cause; }; static struct cr_filter cr_filter[] = { @@ -704,18 +710,36 @@ static struct cr_filter cr_filter[] = { .length = sizeof(bssmap_cr), .result = 1, .contype = NAT_CON_TYPE_CM_SERV_REQ, + .nat_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .nat_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, }, { .data = bss_lu, .length = sizeof(bss_lu), .result = 1, .contype = NAT_CON_TYPE_LU, + .nat_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .nat_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, }, { .data = pag_resp, .length = sizeof(pag_resp), .result = 1, .contype = NAT_CON_TYPE_PAG_RESP, + .nat_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .nat_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, }, { /* nat deny is before blank/null BSC */ @@ -724,6 +748,12 @@ static struct cr_filter cr_filter[] = { .result = -3, .nat_imsi_deny = "[0-9]*", .contype = NAT_CON_TYPE_LU, + .nat_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .nat_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, }, { /* BSC allow is before NAT deny */ @@ -733,6 +763,12 @@ static struct cr_filter cr_filter[] = { .nat_imsi_deny = "[0-9]*", .bsc_imsi_allow = "2440[0-9]*", .contype = NAT_CON_TYPE_LU, + .nat_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .nat_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, }, { /* BSC allow is before NAT deny */ @@ -742,6 +778,12 @@ static struct cr_filter cr_filter[] = { .bsc_imsi_allow = "[0-9]*", .nat_imsi_deny = "[0-9]*", .contype = NAT_CON_TYPE_LU, + .nat_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .nat_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, }, { /* filter as deny is first */ @@ -752,6 +794,12 @@ static struct cr_filter cr_filter[] = { .bsc_imsi_allow = "[0-9]*", .nat_imsi_deny = "[0-9]*", .contype = NAT_CON_TYPE_LU, + .nat_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .nat_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, }, { /* deny by nat rule */ @@ -761,6 +809,27 @@ static struct cr_filter cr_filter[] = { .bsc_imsi_deny = "000[0-9]*", .nat_imsi_deny = "[0-9]*", .contype = NAT_CON_TYPE_LU, + .nat_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .nat_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + }, + { + /* deny by nat rule */ + .data = bss_lu, + .length = sizeof(bss_lu), + .result = -3, + .bsc_imsi_deny = "000[0-9]*", + .nat_imsi_deny = "[0-9]*", + .contype = NAT_CON_TYPE_LU, + .nat_cm_reject_cause = 0x23, + .nat_lu_reject_cause = 0x42, + .bsc_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_lu_reject_cause = 0x42, + .want_cm_reject_cause = 0x23, }, { /* deny by bsc rule */ @@ -769,8 +838,27 @@ static struct cr_filter cr_filter[] = { .result = -2, .bsc_imsi_deny = "[0-9]*", .contype = NAT_CON_TYPE_LU, + .nat_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .nat_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .want_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + }, + { + /* deny by bsc rule */ + .data = bss_lu, + .length = sizeof(bss_lu), + .result = -2, + .bsc_imsi_deny = "[0-9]*", + .contype = NAT_CON_TYPE_LU, + .nat_cm_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .nat_lu_reject_cause = GSM48_REJECT_PLMN_NOT_ALLOWED, + .bsc_cm_reject_cause = 0x42, + .bsc_lu_reject_cause = 0x23, + .want_lu_reject_cause = 0x23, + .want_cm_reject_cause = 0x42, }, - }; static void test_cr_filter() @@ -795,11 +883,20 @@ static void test_cr_filter() bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst); nat_entry = bsc_nat_acc_lst_entry_create(nat_lst); + /* test the default value as we are going to overwrite it */ + OSMO_ASSERT(bsc_entry->cm_reject_cause == GSM48_REJECT_PLMN_NOT_ALLOWED); + OSMO_ASSERT(bsc_entry->lu_reject_cause == GSM48_REJECT_PLMN_NOT_ALLOWED); + for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) { char *imsi; msgb_reset(msg); copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length); + bsc_entry->cm_reject_cause = cr_filter[i].bsc_cm_reject_cause; + bsc_entry->lu_reject_cause = cr_filter[i].bsc_lu_reject_cause; + nat_entry->cm_reject_cause = cr_filter[i].nat_cm_reject_cause; + nat_entry->lu_reject_cause = cr_filter[i].nat_lu_reject_cause; + if (gsm_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny, cr_filter[i].nat_imsi_deny ? 1 : 0, &cr_filter[i].nat_imsi_deny) != 0) @@ -826,6 +923,10 @@ static void test_cr_filter() abort(); } + + OSMO_ASSERT(cause.cm_reject_cause == cr_filter[i].want_cm_reject_cause); + OSMO_ASSERT(cause.lu_reject_cause == cr_filter[i].want_lu_reject_cause); + if (contype != cr_filter[i].contype) { printf("FAIL: Wrong contype %d for test %d.\n", res, contype); abort();