diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2011-01-23 23:31:26 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2011-01-24 15:35:08 +0100 |
commit | ea5ce23d72cbb6571862a4356ca21890aae5ecc9 (patch) | |
tree | f21942c09ed14873540e8b96d3e551fa08e50d36 | |
parent | 8ade9b7bc235b644a1ce63ba0db9e855b118d267 (diff) |
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.
-rw-r--r-- | include/mtp_data.h | 5 | ||||
-rw-r--r-- | src/link_udp.c | 26 | ||||
-rw-r--r-- | src/mtp_link.c | 14 | ||||
-rw-r--r-- | src/sctp_m2ua.c | 14 |
4 files changed, 49 insertions, 10 deletions
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 @@ struct mtp_link { /* link test routine */ uint8_t test_ptrn[14]; + int blocked; + int link_no; int sltm_pending; int was_up; @@ -120,6 +122,9 @@ int mtp_link_set_submit_isup_data(struct mtp_link_set *link, int sls, const uint 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 @@ static int udp_read_cb(struct bsc_fd *fd) 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 @@ static int udp_link_reset(struct mtp_link *link) 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 @@ static int udp_link_start(struct mtp_link *link) 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 @@ void snmp_mtp_callback(struct snmp_mtp_session *session, 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 @@ void snmp_mtp_callback(struct snmp_mtp_session *session, * 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 @@ void mtp_link_failure(struct mtp_link *link) 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 @@ static int m2ua_handle_data(struct sctp_m2ua_conn *conn, 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 @@ static int sctp_trans_accept(struct bsc_fd *fd, unsigned int what) 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 @@ struct mtp_m2ua_link *sctp_m2ua_transp_create(const char *ip, int port) 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; |