filter: Move the access list management around
diff --git a/openbsc/include/openbsc/bsc_msg_filter.h b/openbsc/include/openbsc/bsc_msg_filter.h
index d9b3f6b..248a082 100644
--- a/openbsc/include/openbsc/bsc_msg_filter.h
+++ b/openbsc/include/openbsc/bsc_msg_filter.h
@@ -8,6 +8,7 @@
 #include <regex.h>
 
 /* TODO: remove */
+struct bsc_nat;
 struct bsc_nat_parsed;
 struct bsc_connection;
 struct nat_sccp_connection;
@@ -69,3 +70,11 @@
 			struct nat_sccp_connection *con, struct bsc_nat_parsed *parsed,
 			struct bsc_nat_reject_cause *cause);
 
+/* IMSI allow/deny handling */
+struct bsc_nat_acc_lst *bsc_nat_acc_lst_find(struct bsc_nat *nat, const char *name);
+struct bsc_nat_acc_lst *bsc_nat_acc_lst_get(struct bsc_nat *nat, const char *name);
+void bsc_nat_acc_lst_delete(struct bsc_nat_acc_lst *lst);
+
+struct bsc_nat_acc_lst_entry *bsc_nat_acc_lst_entry_create(struct bsc_nat_acc_lst *);
+int bsc_nat_lst_check_allow(struct bsc_nat_acc_lst *lst, const char *imsi);
+
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index de709c3..b9f1e56 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -390,14 +390,6 @@
 int bsc_write_msg(struct osmo_wqueue *queue, struct msgb *msg);
 int bsc_write_cb(struct osmo_fd *bfd, struct msgb *msg);
 
-/* IMSI allow/deny handling */
-struct bsc_nat_acc_lst *bsc_nat_acc_lst_find(struct bsc_nat *nat, const char *name);
-struct bsc_nat_acc_lst *bsc_nat_acc_lst_get(struct bsc_nat *nat, const char *name);
-void bsc_nat_acc_lst_delete(struct bsc_nat_acc_lst *lst);
-
-struct bsc_nat_acc_lst_entry *bsc_nat_acc_lst_entry_create(struct bsc_nat_acc_lst *);
-int bsc_nat_lst_check_allow(struct bsc_nat_acc_lst *lst, const char *imsi);
-
 int bsc_nat_msc_is_connected(struct bsc_nat *nat);
 
 int bsc_conn_type_to_ctr(struct nat_sccp_connection *conn);
diff --git a/openbsc/src/libfilter/Makefile.am b/openbsc/src/libfilter/Makefile.am
index e24ec5f..d79afb2 100644
--- a/openbsc/src/libfilter/Makefile.am
+++ b/openbsc/src/libfilter/Makefile.am
@@ -5,5 +5,6 @@
 noinst_LIBRARIES = libfilter.a
 
 libfilter_a_SOURCES = \
-	bsc_msg_filter.c
+	bsc_msg_filter.c \
+	bsc_msg_acc.c
 
diff --git a/openbsc/src/libfilter/bsc_msg_acc.c b/openbsc/src/libfilter/bsc_msg_acc.c
new file mode 100644
index 0000000..947a7b2
--- /dev/null
+++ b/openbsc/src/libfilter/bsc_msg_acc.c
@@ -0,0 +1,116 @@
+/*
+ * (C) 2010-2015 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2011 by On-Waves
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <openbsc/bsc_msg_filter.h>
+#include <openbsc/bsc_nat.h>
+
+#include <osmocom/core/rate_ctr.h>
+
+#include <string.h>
+
+static const struct rate_ctr_desc acc_list_ctr_description[] = {
+	[ACC_LIST_BSC_FILTER]	= { "access-list.bsc-filter", "Rejected by rule for BSC"},
+	[ACC_LIST_NAT_FILTER]	= { "access-list.nat-filter", "Rejected by rule for NAT"},
+};
+
+static const struct rate_ctr_group_desc bsc_cfg_acc_list_desc = {
+	.group_name_prefix = "nat.filter",
+	.group_description = "NAT Access-List Statistics",
+	.num_ctr = ARRAY_SIZE(acc_list_ctr_description),
+	.ctr_desc = acc_list_ctr_description,
+};
+
+
+int bsc_nat_lst_check_allow(struct bsc_nat_acc_lst *lst, const char *mi_string)
+{
+	struct bsc_nat_acc_lst_entry *entry;
+
+	llist_for_each_entry(entry, &lst->fltr_list, list) {
+		if (!entry->imsi_allow)
+			continue;
+		if (regexec(&entry->imsi_allow_re, mi_string, 0, NULL, 0) == 0)
+			return 0;
+	}
+
+	return 1;
+}
+
+struct bsc_nat_acc_lst *bsc_nat_acc_lst_find(struct bsc_nat *nat, const char *name)
+{
+	struct bsc_nat_acc_lst *lst;
+
+	if (!name)
+		return NULL;
+
+	llist_for_each_entry(lst, &nat->access_lists, list)
+		if (strcmp(lst->name, name) == 0)
+			return lst;
+
+	return NULL;
+}
+
+struct bsc_nat_acc_lst *bsc_nat_acc_lst_get(struct bsc_nat *nat, const char *name)
+{
+	struct bsc_nat_acc_lst *lst;
+
+	lst = bsc_nat_acc_lst_find(nat, name);
+	if (lst)
+		return lst;
+
+	lst = talloc_zero(nat, struct bsc_nat_acc_lst);
+	if (!lst) {
+		LOGP(DNAT, LOGL_ERROR, "Failed to allocate access list");
+		return NULL;
+	}
+
+	/* TODO: get the index right */
+	lst->stats = rate_ctr_group_alloc(lst, &bsc_cfg_acc_list_desc, 0);
+	if (!lst->stats) {
+		talloc_free(lst);
+		return NULL;
+	}
+
+	INIT_LLIST_HEAD(&lst->fltr_list);
+	lst->name = talloc_strdup(lst, name);
+	llist_add_tail(&lst->list, &nat->access_lists);
+	return lst;
+}
+
+void bsc_nat_acc_lst_delete(struct bsc_nat_acc_lst *lst)
+{
+	llist_del(&lst->list);
+	rate_ctr_group_free(lst->stats);
+	talloc_free(lst);
+}
+
+struct bsc_nat_acc_lst_entry *bsc_nat_acc_lst_entry_create(struct bsc_nat_acc_lst *lst)
+{
+	struct bsc_nat_acc_lst_entry *entry;
+
+	entry = talloc_zero(lst, struct bsc_nat_acc_lst_entry);
+	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/src/osmo-bsc_nat/bsc_nat_utils.c b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
index e658569..33582ff 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
@@ -67,18 +67,6 @@
 	.ctr_desc = bsc_cfg_ctr_description,
 };
 
-static const struct rate_ctr_desc acc_list_ctr_description[] = {
-	[ACC_LIST_BSC_FILTER]	= { "access-list.bsc-filter", "Rejected by rule for BSC"},
-	[ACC_LIST_NAT_FILTER]	= { "access-list.nat-filter", "Rejected by rule for NAT"},
-};
-
-static const struct rate_ctr_group_desc bsc_cfg_acc_list_desc = {
-	.group_name_prefix = "nat.filter",
-	.group_description = "NAT Access-List Statistics",
-	.num_ctr = ARRAY_SIZE(acc_list_ctr_description),
-	.ctr_desc = acc_list_ctr_description,
-};
-
 struct bsc_nat *bsc_nat_alloc(void)
 {
 	struct bsc_nat *nat = talloc_zero(tall_bsc_ctx, struct bsc_nat);
@@ -393,20 +381,6 @@
 	return 0;
 }
 
-int bsc_nat_lst_check_allow(struct bsc_nat_acc_lst *lst, const char *mi_string)
-{
-	struct bsc_nat_acc_lst_entry *entry;
-
-	llist_for_each_entry(entry, &lst->fltr_list, list) {
-		if (!entry->imsi_allow)
-			continue;
-		if (regexec(&entry->imsi_allow_re, mi_string, 0, NULL, 0) == 0)
-			return 0;
-	}
-
-	return 1;
-}
-
 struct gsm48_hdr *bsc_unpack_dtap(struct bsc_nat_parsed *parsed,
 				  struct msgb *msg, uint32_t *len)
 {
@@ -443,68 +417,6 @@
 	return con_types[type];
 }
 
-struct bsc_nat_acc_lst *bsc_nat_acc_lst_find(struct bsc_nat *nat, const char *name)
-{
-	struct bsc_nat_acc_lst *lst;
-
-	if (!name)
-		return NULL;
-
-	llist_for_each_entry(lst, &nat->access_lists, list)
-		if (strcmp(lst->name, name) == 0)
-			return lst;
-
-	return NULL;
-}
-
-struct bsc_nat_acc_lst *bsc_nat_acc_lst_get(struct bsc_nat *nat, const char *name)
-{
-	struct bsc_nat_acc_lst *lst;
-
-	lst = bsc_nat_acc_lst_find(nat, name);
-	if (lst)
-		return lst;
-
-	lst = talloc_zero(nat, struct bsc_nat_acc_lst);
-	if (!lst) {
-		LOGP(DNAT, LOGL_ERROR, "Failed to allocate access list");
-		return NULL;
-	}
-
-	/* TODO: get the index right */
-	lst->stats = rate_ctr_group_alloc(lst, &bsc_cfg_acc_list_desc, 0);
-	if (!lst->stats) {
-		talloc_free(lst);
-		return NULL;
-	}
-
-	INIT_LLIST_HEAD(&lst->fltr_list);
-	lst->name = talloc_strdup(lst, name);
-	llist_add_tail(&lst->list, &nat->access_lists);
-	return lst;
-}
-
-void bsc_nat_acc_lst_delete(struct bsc_nat_acc_lst *lst)
-{
-	llist_del(&lst->list);
-	rate_ctr_group_free(lst->stats);
-	talloc_free(lst);
-}
-
-struct bsc_nat_acc_lst_entry *bsc_nat_acc_lst_entry_create(struct bsc_nat_acc_lst *lst)
-{
-	struct bsc_nat_acc_lst_entry *entry;
-
-	entry = talloc_zero(lst, struct bsc_nat_acc_lst_entry);
-	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;
-}
-
 int bsc_nat_msc_is_connected(struct bsc_nat *nat)
 {
 	return nat->msc_con->is_connected;
diff --git a/openbsc/src/osmo-bsc_nat/bsc_ussd.c b/openbsc/src/osmo-bsc_nat/bsc_ussd.c
index 67844b8..48626b1 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_ussd.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_ussd.c
@@ -22,6 +22,7 @@
 
 #include <openbsc/bsc_nat.h>
 #include <openbsc/bsc_nat_sccp.h>
+#include <openbsc/bsc_msg_filter.h>
 #include <openbsc/ipaccess.h>
 #include <openbsc/socket.h>