9
0
Fork 0

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.
This commit is contained in:
Holger Hans Peter Freyther 2011-02-17 02:18:38 +01:00
parent ea247c1d0a
commit 6c0b2e570c
10 changed files with 133 additions and 71 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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",

View File

@ -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)

View File

@ -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,

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
if (!lnk) {
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;

View File

@ -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; \