From 6c0b2e570c56b79ccb4e0905e3d2288fc55443e2 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 17 Feb 2011 02:18:38 +0100 Subject: mtp: Make the mtp_link point to a specific type of link We might want to be able to change the type of a link at runtime. Decouple the link and the actual type of the link. --- include/bsc_data.h | 2 +- include/mtp_data.h | 15 ++++++++-- include/sctp_m2ua.h | 2 +- src/link_udp.c | 26 ++++++++-------- src/links.c | 10 ++++--- src/main_stp.c | 2 -- src/mtp_layer3.c | 12 -------- src/mtp_link.c | 85 +++++++++++++++++++++++++++++++++++++++++++---------- src/sctp_m2ua.c | 39 ++++++++++++++++-------- src/vty_interface.c | 9 ++---- 10 files changed, 132 insertions(+), 70 deletions(-) diff --git a/include/bsc_data.h b/include/bsc_data.h index c09d922..83061e2 100644 --- a/include/bsc_data.h +++ b/include/bsc_data.h @@ -46,7 +46,7 @@ struct mtp_udp_data { struct mtp_udp_link { /* subclass */ - struct mtp_link base; + struct mtp_link *base; /* UDP specific stuff */ struct bsc_data *bsc; diff --git a/include/mtp_data.h b/include/mtp_data.h index eed113f..48a2b10 100644 --- a/include/mtp_data.h +++ b/include/mtp_data.h @@ -37,6 +37,12 @@ struct ss7_application; #define MTP_T2 30, 0 #define START_DELAY 8, 0 +enum ss7_link_type { + SS7_LTYPE_NONE, + SS7_LTYPE_UDP, + SS7_LTYPE_M2UA, +}; + /** * The state of the mtp_link in terms of layer3 and upwards */ @@ -120,6 +126,10 @@ struct mtp_link { int (*shutdown)(struct mtp_link *); int (*reset)(struct mtp_link *data); int (*clear_queue)(struct mtp_link *data); + + /* private data */ + enum ss7_link_type type; + void *data; }; @@ -130,7 +140,6 @@ int mtp_link_set_submit_sccp_data(struct mtp_link_set *link, int sls, const uint int mtp_link_set_submit_isup_data(struct mtp_link_set *link, int sls, const uint8_t *data, unsigned int length); 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); @@ -147,7 +156,6 @@ int mtp_link_set_send(struct mtp_link_set *set, struct msgb *msg); void mtp_link_down(struct mtp_link *data); void mtp_link_up(struct mtp_link *data); -int mtp_link_init(struct mtp_link *link); void mtp_link_start_link_test(struct mtp_link *link); void mtp_link_stop_link_test(struct mtp_link *link); int mtp_link_slta(struct mtp_link *link, uint16_t l3_len, struct mtp_level_3_mng *mng); @@ -161,4 +169,7 @@ struct msgb *mtp_msg_alloc(struct mtp_link_set *link); struct mtp_link_set *mtp_link_set_alloc(struct bsc_data *bsc); struct mtp_link_set *mtp_link_set_num(struct bsc_data *bsc, int num); +struct mtp_link *mtp_link_alloc(struct mtp_link_set *set); +struct mtp_link *mtp_link_num(struct mtp_link_set *set, int num); + #endif diff --git a/include/sctp_m2ua.h b/include/sctp_m2ua.h index 1c001cd..9f4d5c7 100644 --- a/include/sctp_m2ua.h +++ b/include/sctp_m2ua.h @@ -42,7 +42,7 @@ struct sctp_m2ua_transport { }; struct mtp_m2ua_link { - struct mtp_link base; + struct mtp_link *base; int link_index; struct llist_head entry; diff --git a/src/link_udp.c b/src/link_udp.c index bcf8ec6..b7d9200 100644 --- a/src/link_udp.c +++ b/src/link_udp.c @@ -61,7 +61,7 @@ static int udp_write_cb(struct bsc_fd *fd, struct msgb *msg) } LOGP(DINP, LOGL_DEBUG, "Sending MSU: %s\n", hexdump(msg->data, msg->len)); - mtp_handle_pcap(&link->base, NET_OUT, msg->l2h, msgb_l2len(msg)); + mtp_handle_pcap(link->base, NET_OUT, msg->l2h, msgb_l2len(msg)); /* the assumption is we have connected the socket to the remote */ rc = sendto(fd->fd, msg->data, msg->len, 0, @@ -77,6 +77,7 @@ static int udp_write_cb(struct bsc_fd *fd, struct msgb *msg) static int udp_read_cb(struct bsc_fd *fd) { struct mtp_udp_data *data; + struct mtp_udp_link *ulnk; struct mtp_link *link; struct udp_data_hdr *hdr; struct msgb *msg; @@ -99,14 +100,15 @@ static int udp_read_cb(struct bsc_fd *fd) } hdr = (struct udp_data_hdr *) msgb_put(msg, sizeof(*hdr)); - link = (struct mtp_link *) find_link(data, ntohs(hdr->data_link_index)); + ulnk = find_link(data, ntohs(hdr->data_link_index)); - if (!link) { + if (!ulnk) { LOGP(DINP, LOGL_ERROR, "No link registered for %d\n", ntohs(hdr->data_link_index)); goto exit; } + link = ulnk->base; if (link->blocked) { LOGP(DINP, LOGL_ERROR, "The link is blocked.\n"); rc = 0; @@ -181,7 +183,7 @@ static int udp_link_reset(struct mtp_link *link) { struct mtp_udp_link *ulnk; - ulnk = (struct mtp_udp_link *) link; + ulnk = (struct mtp_udp_link *) link->data; snmp_mtp_deactivate(ulnk->session, ulnk->link_index); return 0; @@ -197,7 +199,7 @@ static int udp_link_write(struct mtp_link *link, struct msgb *msg) struct mtp_udp_link *ulnk; struct udp_data_hdr *hdr; - ulnk = (struct mtp_udp_link *) link; + ulnk = (struct mtp_udp_link *) link->data; hdr = (struct udp_data_hdr *) msgb_push(msg, sizeof(*hdr)); hdr->format_type = UDP_FORMAT_SIMPLE_UDP; @@ -233,12 +235,12 @@ int link_udp_init(struct mtp_udp_link *link, char *remote, int port) link->session->data = link; /* function table */ - link->base.shutdown = udp_link_shutdown; - link->base.clear_queue = udp_link_dummy; + link->base->shutdown = udp_link_shutdown; + link->base->clear_queue = udp_link_dummy; - link->base.reset = udp_link_reset; - link->base.start = udp_link_start; - link->base.write = udp_link_write; + link->base->reset = udp_link_reset; + link->base->start = udp_link_start; + link->base->write = udp_link_write; /* prepare the remote */ memset(&link->remote, 0, sizeof(link->remote)); @@ -317,7 +319,7 @@ void snmp_mtp_callback(struct snmp_mtp_session *session, if (!ulink) return LOGP(DINP, LOGL_ERROR, "Failed to find link_id %d\n", link_id); - link = &ulink->base; + link = ulink->base; if (res == SNMP_STATUS_TIMEOUT && !link->blocked) { LOGP(DINP, LOGL_ERROR, "Failed to restart link: %s/%d\n", @@ -338,7 +340,7 @@ void snmp_mtp_callback(struct snmp_mtp_session *session, */ if (!link->blocked) { link->link_activate.cb = do_start; - link->link_activate.data = link; + link->link_activate.data = ulink; bsc_schedule_timer(&link->link_activate, ulink->reset_timeout, 0); LOGP(DINP, LOGL_NOTICE, "Will bring up link %s/%d in %d seconds.\n", diff --git a/src/links.c b/src/links.c index ccc8bfb..fae1dea 100644 --- a/src/links.c +++ b/src/links.c @@ -90,6 +90,7 @@ struct mtp_link_set *link_init(struct bsc_data *bsc) { int i; struct mtp_udp_link *lnk; + struct mtp_link *blnk; struct mtp_link_set *set; set = mtp_link_set_alloc(bsc); @@ -121,14 +122,15 @@ struct mtp_link_set *link_init(struct bsc_data *bsc) for (i = 1; i <= bsc->udp_nr_links; ++i) { - lnk = talloc_zero(set, struct mtp_udp_link); - lnk->base.pcap_fd = -1; + blnk = mtp_link_alloc(set); + lnk = talloc_zero(blnk, struct mtp_udp_link); + lnk->base = blnk; + lnk->base->data = lnk; + lnk->base->type = SS7_LTYPE_UDP; lnk->bsc = bsc; lnk->data = &bsc->udp_data; lnk->link_index = i; lnk->reset_timeout = bsc->udp_reset_timeout; - mtp_link_set_add_link(set, (struct mtp_link *) lnk); - /* now connect to the transport */ if (link_udp_init(lnk, bsc->udp_ip, bsc->udp_port) != 0) diff --git a/src/main_stp.c b/src/main_stp.c index a4694b9..ba204a7 100644 --- a/src/main_stp.c +++ b/src/main_stp.c @@ -275,8 +275,6 @@ int main(int argc, char **argv) m2ua_set->pass_all_isup = bsc->isup_pass; lnk = mtp_m2ua_link_create(bsc->m2ua_trans, m2ua_set); - lnk->base.pcap_fd = -1; - mtp_link_set_add_link(m2ua_set, (struct mtp_link *) lnk); ss7_application_setup(app, APP_STP, SS7_SET_LINKSET, 0, diff --git a/src/mtp_layer3.c b/src/mtp_layer3.c index 83c8d63..0ef416c 100644 --- a/src/mtp_layer3.c +++ b/src/mtp_layer3.c @@ -582,18 +582,6 @@ 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 *lnk) -{ - lnk->set = set; - lnk->link_no = set->nr_links++; - if (mtp_link_init(lnk) != 0) - return -1; - - llist_add_tail(&lnk->entry, &set->links); - mtp_link_set_init_slc(set); - return 0; -} - struct mtp_link_set *mtp_link_set_alloc(struct bsc_data *bsc) { struct mtp_link_set *link; diff --git a/src/mtp_link.c b/src/mtp_link.c index 009547c..142d78a 100644 --- a/src/mtp_link.c +++ b/src/mtp_link.c @@ -24,6 +24,8 @@ #include #include +#include + #include static struct msgb *mtp_create_sltm(struct mtp_link *link) @@ -114,22 +116,6 @@ static void mtp_sltm_t2_timeout(void *_link) bsc_schedule_timer(&link->t2_timer, MTP_T2); } -int mtp_link_init(struct mtp_link *link) -{ - link->ctrg = rate_ctr_group_alloc(link, - mtp_link_rate_ctr_desc(), link->link_no); - if (!link->ctrg) { - LOGP(DINP, LOGL_ERROR, "Failed to allocate rate_ctr.\n"); - return -1; - } - - link->t1_timer.data = link; - link->t1_timer.cb = mtp_sltm_t1_timeout; - link->t2_timer.data = link; - link->t2_timer.cb = mtp_sltm_t2_timeout; - return 0; -} - void mtp_link_stop_link_test(struct mtp_link *link) { bsc_del_timer(&link->t1_timer); @@ -196,3 +182,70 @@ void mtp_link_unblock(struct mtp_link *link) link->blocked = 0; link->reset(link); } + +static int dummy_arg1(struct mtp_link *link) +{ + LOGP(DINP, LOGL_ERROR, "The link %d of linkset %d/%s is not typed.\n", + link->link_no, link->set->nr, link->set->name); + return 0; +} + +static int dummy_arg2(struct mtp_link *link, struct msgb *msg) +{ + LOGP(DINP, LOGL_ERROR, "The link %d of linkset %d/%s is not typed.\n", + link->link_no, link->set->nr, link->set->name); + msgb_free(msg); + return 0; +} + +struct mtp_link *mtp_link_alloc(struct mtp_link_set *set) +{ + struct mtp_link *link; + + link = talloc_zero(set, struct mtp_link); + if (!link) { + LOGP(DINP, LOGL_ERROR, "Failed to allocate the link.\n"); + return NULL; + } + + link->link_no = set->nr_links++; + link->ctrg = rate_ctr_group_alloc(link, + mtp_link_rate_ctr_desc(), link->link_no); + if (!link->ctrg) { + LOGP(DINP, LOGL_ERROR, "Failed to allocate rate_ctr.\n"); + talloc_free(link); + return NULL; + } + + /* make sure a unconfigured link does not crash */ + link->start = dummy_arg1; + link->write = dummy_arg2; + link->shutdown = dummy_arg1; + link->reset = dummy_arg1; + link->clear_queue = dummy_arg1; + + link->pcap_fd = -1; + + link->t1_timer.data = link; + link->t1_timer.cb = mtp_sltm_t1_timeout; + link->t2_timer.data = link; + link->t2_timer.cb = mtp_sltm_t2_timeout; + + link->set = set; + + llist_add_tail(&link->entry, &set->links); + mtp_link_set_init_slc(set); + + return link; +} + +struct mtp_link *mtp_link_num(struct mtp_link_set *set, int num) +{ + struct mtp_link *link; + + llist_for_each_entry(link, &set->links, entry) + if (link->link_no == num) + return link; + + return NULL; +} diff --git a/src/sctp_m2ua.c b/src/sctp_m2ua.c index 284bf8a..155043d 100644 --- a/src/sctp_m2ua.c +++ b/src/sctp_m2ua.c @@ -61,7 +61,7 @@ static void m2ua_conn_destroy(struct sctp_m2ua_conn *conn) /* TODO: hardcoded link index */ link = find_m2ua_link(conn->trans, 0); if (link && conn->asp_up && conn->asp_active && conn->established) - link_down(&link->base); + link_down(link->base); talloc_free(conn); #warning "Notify any other AS(P) for failover scenario" @@ -288,7 +288,7 @@ static int m2ua_handle_est_req(struct mtp_m2ua_link *link, conn->established = 1; LOGP(DINP, LOGL_NOTICE, "M2UA/Link is established.\n"); - mtp_link_up(&link->base); + mtp_link_up(link->base); m2ua_msg_free(conf); return 0; } @@ -314,7 +314,7 @@ static int m2ua_handle_rel_req(struct mtp_m2ua_link *link, conn->established = 0; LOGP(DINP, LOGL_NOTICE, "M2UA/Link is released.\n"); - link_down(&link->base); + link_down(link->base); m2ua_msg_free(conf); return 0; } @@ -348,7 +348,7 @@ static int m2ua_handle_data(struct mtp_m2ua_link *_link, msg->l2h = msgb_put(msg, data->len); memcpy(msg->l2h, data->dat, data->len); - link = &_link->base; + link = _link->base; if (!link->blocked) { mtp_handle_pcap(link, NET_IN, msg->l2h, msgb_l2len(msg)); mtp_link_set_data(link, msg); @@ -496,7 +496,7 @@ static int sctp_m2ua_write(struct mtp_link *link, struct msgb *msg) struct m2ua_msg *m2ua; uint32_t interface; - mlink = (struct mtp_m2ua_link *) link; + mlink = (struct mtp_m2ua_link *) link->data; trans = mlink->transport; if (llist_empty(&trans->conns)) @@ -616,7 +616,7 @@ static int sctp_m2ua_dummy(struct mtp_link *link) static int sctp_m2ua_start(struct mtp_link *_link) { - struct mtp_m2ua_link *link = (struct mtp_m2ua_link *) _link; + struct mtp_m2ua_link *link = (struct mtp_m2ua_link *) _link->data; link->transport->started = 1; return 0; @@ -625,7 +625,7 @@ static int sctp_m2ua_start(struct mtp_link *_link) static int sctp_m2ua_reset(struct mtp_link *_link) { struct sctp_m2ua_conn *conn, *tmp; - struct mtp_m2ua_link *link = (struct mtp_m2ua_link *) _link; + struct mtp_m2ua_link *link = (struct mtp_m2ua_link *) _link->data; /* TODO: only connection that use the current link index! */ llist_for_each_entry_safe(conn, tmp, &link->transport->conns, entry) @@ -694,22 +694,35 @@ struct sctp_m2ua_transport *sctp_m2ua_transp_create(const char *ip, int port) struct mtp_m2ua_link *mtp_m2ua_link_create(struct sctp_m2ua_transport *trans, struct mtp_link_set *set) { + struct mtp_link *blnk; struct mtp_m2ua_link *lnk; - lnk = talloc_zero(set, struct mtp_m2ua_link); + blnk = mtp_link_alloc(set); + if (!blnk) { + LOGP(DINP, LOGL_ERROR, "Failed to allocate.\n"); + return NULL; + } + + lnk = talloc_zero(blnk, struct mtp_m2ua_link); if (!lnk) { LOGP(DINP, LOGL_ERROR, "Failed to allocate.\n"); + talloc_free(blnk); return NULL; } + /* make sure we can resolve it both ways */ + lnk->base = blnk; + blnk->data = lnk; + blnk->type = SS7_LTYPE_M2UA; + /* remember we have a link here */ llist_add(&lnk->entry, &trans->links); - lnk->base.shutdown = sctp_m2ua_reset; - lnk->base.clear_queue = sctp_m2ua_dummy; - lnk->base.reset = sctp_m2ua_reset; - lnk->base.start = sctp_m2ua_start; - lnk->base.write = sctp_m2ua_write; + lnk->base->shutdown = sctp_m2ua_reset; + lnk->base->clear_queue = sctp_m2ua_dummy; + lnk->base->reset = sctp_m2ua_reset; + lnk->base->start = sctp_m2ua_start; + lnk->base->write = sctp_m2ua_write; lnk->transport = trans; return lnk; diff --git a/src/vty_interface.c b/src/vty_interface.c index 0c1cb3d..06df291 100644 --- a/src/vty_interface.c +++ b/src/vty_interface.c @@ -494,18 +494,13 @@ DEFUN(pcap_set_stop, pcap_set_stop_cmd, #define FIND_LINK(vty, set_no, nr) ({ \ struct mtp_link_set *set = NULL; \ - struct mtp_link *link = NULL, *tmp; \ + struct mtp_link *link = NULL; \ set = mtp_link_set_num(bsc, set_no); \ if (!set) { \ vty_out(vty, "Unknown Linkset nr %d.%s", set_no, VTY_NEWLINE); \ return CMD_WARNING; \ } \ - llist_for_each_entry(tmp, &set->links, entry) { \ - if (tmp->link_no == nr) { \ - link = tmp; \ - break; \ - } \ - } \ + link = mtp_link_num(set, nr); \ if (!link) { \ vty_out(vty, "Can not find link %d.%s", nr, VTY_NEWLINE); \ return CMD_WARNING; \ -- cgit v1.2.3