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:
parent
ea247c1d0a
commit
6c0b2e570c
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
10
src/links.c
10
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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; \
|
||||
|
|
Reference in New Issue