nat: Keep track of how many connections we reject

Keep track of how many connections we reject due the IMSI
filter itself or due not being able to parse the message.
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index f988a8f..3abf231 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -96,6 +96,9 @@
 	BCFG_CTR_NET_RECONN,
 	BCFG_CTR_DROPPED_SCCP,
 	BCFG_CTR_DROPPED_CALLS,
+	BCFG_CTR_REJECTED_CR,
+	BCFG_CTR_REJECTED_MSG,
+	BCFG_CTR_ILL_PACKET,
 };
 
 /**
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index 838e8f9..4df7758 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -77,6 +77,7 @@
 static struct bsc_nat *nat;
 static void bsc_send_data(struct bsc_connection *bsc, const uint8_t *data, unsigned int length, int);
 static void msc_send_reset(struct bsc_msc_connection *con);
+static void bsc_stat_reject(int filter, struct bsc_connection *bsc, int normal);
 
 struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num)
 {
@@ -305,6 +306,29 @@
 }
 
 /*
+ * Update the release statistics
+ */
+static void bsc_stat_reject(int filter, struct bsc_connection *bsc, int normal)
+{
+	if (!bsc->cfg) {
+		LOGP(DNAT, LOGL_ERROR, "BSC is not authenticated.");
+		return;
+	}
+
+	if (filter >= 0) {
+		LOGP(DNAT, LOGL_ERROR, "Connection was not rejected");
+		return;
+	}
+
+	if (filter == -1)
+		rate_ctr_inc(&bsc->cfg->stats.ctrg->ctr[BCFG_CTR_ILL_PACKET]);
+	else if (normal)
+		rate_ctr_inc(&bsc->cfg->stats.ctrg->ctr[BCFG_CTR_REJECTED_MSG]);
+	else
+		rate_ctr_inc(&bsc->cfg->stats.ctrg->ctr[BCFG_CTR_REJECTED_CR]);
+}
+
+/*
  * Release an established connection. We will have to release it to the BSC
  * and to the network and we do it the following way.
  * 1.) Give up on the MSC side
@@ -772,8 +796,11 @@
 		switch (parsed->sccp_type) {
 		case SCCP_MSG_TYPE_CR:
 			filter = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &con_type);
-			if (filter < 0)
+			if (filter < 0) {
+				bsc_stat_reject(filter, bsc, 0);
 				goto exit3;
+			}
+
 			if (!create_sccp_src_ref(bsc, parsed))
 				goto exit2;
 			con = patch_sccp_src_ref_to_msc(msg, parsed, bsc);
@@ -792,6 +819,7 @@
 			if (con) {
 				filter = bsc_nat_filter_dt(bsc, msg, con, parsed);
 				if (filter < 0) {
+					bsc_stat_reject(filter, bsc, 1);
 					bsc_send_con_release(bsc, con);
 					con = NULL;
 					goto exit2;
diff --git a/openbsc/src/nat/bsc_nat_utils.c b/openbsc/src/nat/bsc_nat_utils.c
index e7c8928..77deef4 100644
--- a/openbsc/src/nat/bsc_nat_utils.c
+++ b/openbsc/src/nat/bsc_nat_utils.c
@@ -47,6 +47,9 @@
 	[BCFG_CTR_NET_RECONN]    = { "net.reconnects", "Network reconnects       "},
 	[BCFG_CTR_DROPPED_SCCP]  = { "dropped.sccp",   "Dropped SCCP connections."},
 	[BCFG_CTR_DROPPED_CALLS] = { "dropped.calls",  "Dropped active calls.    "},
+	[BCFG_CTR_REJECTED_CR]   = { "rejected.cr",    "Rejected CR due filter   "},
+	[BCFG_CTR_REJECTED_MSG]  = { "rejected.msg",   "Rejected MSG due filter  "},
+	[BCFG_CTR_ILL_PACKET]    = { "rejected.ill",   "Rejected due parse error "},
 };
 
 static const struct rate_ctr_group_desc bsc_cfg_ctrg_desc = {