nat: Add statistics to the access-list in the NAT

Count how many times we match a BSC or NAT deny. This will
give us the number of how often something should be filtered.
diff --git a/openbsc/src/nat/bsc_nat_utils.c b/openbsc/src/nat/bsc_nat_utils.c
index 3933f1b..e7c8928 100644
--- a/openbsc/src/nat/bsc_nat_utils.c
+++ b/openbsc/src/nat/bsc_nat_utils.c
@@ -56,6 +56,18 @@
 	.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);
@@ -266,6 +278,7 @@
 		if (lst_check_deny(bsc_lst, mi_string) == 0) {
 			LOGP(DNAT, LOGL_ERROR,
 			     "Filtering %s by imsi_deny on bsc nr: %d.\n", mi_string, bsc->cfg->nr);
+			rate_ctr_inc(&bsc_lst->stats->ctr[ACC_LIST_BSC_FILTER]);
 			return -2;
 		}
 
@@ -279,6 +292,7 @@
 		if (lst_check_deny(nat_lst, mi_string) == 0) {
 			LOGP(DNAT, LOGL_ERROR,
 			     "Filtering %s by nat imsi_deny on bsc nr: %d.\n", mi_string, bsc->cfg->nr);
+			rate_ctr_inc(&bsc_lst->stats->ctr[ACC_LIST_NAT_FILTER]);
 			return -3;
 		}
 	}
@@ -556,6 +570,13 @@
 		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);
@@ -565,6 +586,7 @@
 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);
 }