aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-02-17 02:18:38 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2011-02-17 19:34:28 +0100
commit6c0b2e570c56b79ccb4e0905e3d2288fc55443e2 (patch)
tree4aebbcbe745244fad732c751be9c969b508b96ed
parentea247c1d0a30362afd4602acdcd595b4afd616ec (diff)
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.
-rw-r--r--include/bsc_data.h2
-rw-r--r--include/mtp_data.h15
-rw-r--r--include/sctp_m2ua.h2
-rw-r--r--src/link_udp.c26
-rw-r--r--src/links.c10
-rw-r--r--src/main_stp.c2
-rw-r--r--src/mtp_layer3.c12
-rw-r--r--src/mtp_link.c85
-rw-r--r--src/sctp_m2ua.c39
-rw-r--r--src/vty_interface.c9
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 <cellmgr_debug.h>
#include <counter.h>
+#include <osmocore/talloc.h>
+
#include <string.h>
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; \