mtp: Make it possible to block a link.

The semantic of a block is to take the physical
link down, call mtp_link_down and to make sure
that the link remains down and no packets are
forwarded there. The unblock call will reset the
link and this should get it back into operation
again.
diff --git a/include/mtp_data.h b/include/mtp_data.h
index b991f46..1d93f20 100644
--- a/include/mtp_data.h
+++ b/include/mtp_data.h
@@ -90,6 +90,8 @@
 	/* link test routine */
 	uint8_t test_ptrn[14];
 
+	int blocked;
+
 	int link_no;
 	int sltm_pending;
 	int was_up;
@@ -120,6 +122,9 @@
 void mtp_link_set_init_slc(struct mtp_link_set *set);
 int mtp_link_set_add_link(struct mtp_link_set *set, struct mtp_link *link);
 
+void mtp_link_block(struct mtp_link *link);
+void mtp_link_unblock(struct mtp_link *link);
+
 
 /* one time init function */
 void mtp_link_set_init(void);
diff --git a/src/link_udp.c b/src/link_udp.c
index 1e24faf..2dfc34b 100644
--- a/src/link_udp.c
+++ b/src/link_udp.c
@@ -107,6 +107,11 @@
 		goto exit;
 	}
 
+	if (link->blocked) {
+		LOGP(DINP, LOGL_ERROR, "The link is blocked.\n");
+		rc = 0;
+		goto exit;
+	}
 
 	/* throw away data as the link is down */
 	if (link->set->available == 0) {
@@ -167,6 +172,11 @@
 	return 0;
 }
 
+static int udp_link_shutdown(struct mtp_link *link)
+{
+	return udp_link_reset(link);
+}
+
 static int udp_link_write(struct mtp_link *link, struct msgb *msg)
 {
 	struct mtp_udp_link *ulnk;
@@ -202,7 +212,7 @@
 int link_udp_init(struct mtp_udp_link *link, const char *remote, int port)
 {
 	/* function table */
-	link->base.shutdown = udp_link_dummy;
+	link->base.shutdown = udp_link_shutdown;
 	link->base.clear_queue = udp_link_dummy;
 
 	link->base.reset = udp_link_reset;
@@ -296,7 +306,7 @@
 
 	link = &ulink->base;
 
-	if (res == SNMP_STATUS_TIMEOUT) {
+	if (res == SNMP_STATUS_TIMEOUT && !link->blocked) {
 		LOGP(DINP, LOGL_ERROR, "Failed to restart link: %d\n", link_id);
 		udp_link_reset(link);
 		return;
@@ -313,11 +323,13 @@
 		 * restart the link in 90 seconds...
 		 * to force a timeout on the BSC
 		 */
-		link->link_activate.cb = do_start;
-		link->link_activate.data = link;
-		bsc_schedule_timer(&link->link_activate, ulink->reset_timeout, 0);
-		LOGP(DINP, LOGL_NOTICE,
-		     "Will restart SLTM transmission in %d seconds.\n", ulink->reset_timeout);
+		if (!link->blocked) {
+			link->link_activate.cb = do_start;
+			link->link_activate.data = link;
+			bsc_schedule_timer(&link->link_activate, ulink->reset_timeout, 0);
+			LOGP(DINP, LOGL_NOTICE,
+			     "Will restart SLTM transmission in %d seconds.\n", ulink->reset_timeout);
+		}
 		break;
 	default:
 		LOGP(DINP, LOGL_ERROR, "Unknown event %d\n", area);
diff --git a/src/mtp_link.c b/src/mtp_link.c
index d885738..8a55aae 100644
--- a/src/mtp_link.c
+++ b/src/mtp_link.c
@@ -167,3 +167,17 @@
 	rate_ctr_inc(&link->ctrg->ctr[MTP_LNK_ERROR]);
 	link->reset(link);
 }
+
+void mtp_link_block(struct mtp_link *link)
+{
+	link->blocked = 1;
+	link->shutdown(link);
+}
+
+void mtp_link_unblock(struct mtp_link *link)
+{
+	if (!link->blocked)
+		return;
+	link->blocked = 0;
+	link->reset(link);
+}
diff --git a/src/sctp_m2ua.c b/src/sctp_m2ua.c
index 65fde0b..d0e88da 100644
--- a/src/sctp_m2ua.c
+++ b/src/sctp_m2ua.c
@@ -327,8 +327,10 @@
 	memcpy(msg->l2h, data->dat, data->len);
 
 	link = &conn->trans->base;
-	mtp_handle_pcap(link, NET_IN, msg->l2h, msgb_l2len(msg));
-	mtp_link_set_data(link, msg);
+	if (!link->blocked) {
+		mtp_handle_pcap(link, NET_IN, msg->l2h, msgb_l2len(msg));
+		mtp_link_set_data(link, msg);
+	}
 	msgb_free(msg);
 
 	return 0;
@@ -526,6 +528,12 @@
 		return -1;
 	}
 
+	if (!trans->base.blocked) {
+		LOGP(DINP, LOGL_NOTICE, "The link is blocked.\n");
+		close(s);
+		return -1;
+	}
+
 	LOGP(DINP, LOGL_NOTICE, "Got a new SCTP connection.\n");
 	conn = talloc_zero(fd->data, struct sctp_m2ua_conn);
 	if (!conn) {
@@ -621,7 +629,7 @@
 		return NULL;
 	}
 
-	trans->base.shutdown = sctp_m2ua_dummy;
+	trans->base.shutdown = sctp_m2ua_reset;
 	trans->base.clear_queue = sctp_m2ua_dummy;
 	trans->base.reset = sctp_m2ua_reset;
 	trans->base.start = sctp_m2ua_start;